// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

import "google/protobuf/struct.proto";

package com.android.adservices.service.proto.bidding_auction_servers;

// ProtectedAuctionInput is generated and encrypted by the client,
// passed through the untrusted Seller service, and decrypted by the
// SellerFrontEnd service.
// It is the wrapper for all of BuyerInput and other information required
// for the Protected Audience auction.
message ProtectedAuctionInput {
  // Input per buyer.
  // The key in the map corresponds to IGOwner (Interest Group Owner) that
  // is the Buyer / DSP. This  string that can identify a
  // buyer participating in the auction. The value corresponds to plaintext
  // BuyerInput ingested by the buyer for bidding.
  map<string, bytes> buyer_input = 1;

  // Publisher website or app.
  // This is required to construct browser signals for web.
  // It will also be passed via GetBids to buyers for their Buyer KV lookup
  // to fetch trusted bidding signals.
  string publisher_name = 2;

  // A boolean value which indicates if event level debug reporting should be
  // enabled or disabled for this request.
  bool enable_debug_reporting = 3;

  // Globally unique identifier for the client request.
  string generation_id = 4;

  // Consented debugging field.
  ConsentedDebugConfiguration consented_debug_config = 5;

  // Optional.
  // A boolean value which indicates whether temporary unlimited egress should
  // be enabled.
  bool enable_unlimited_egress = 6;

  // Optional field (note: this will become a required field in 2025).
  // The request timestamp represents when the SSP requests an ad auction to be run.
  // For Android, the request timestamp will come from the system clock on the device.
  int64 request_timestamp_ms = 7;

  // Maximum number of ghost winners for K-Anonymity controlled by platform (Chrome,
  // Android) for experimentation.
  // By default this is set to 1 on the server side, hence client should
  // populate the field if and only if they want to override for
  // experimentation.
  optional int32 num_k_anon_ghost_winners = 8;

  // Clients can indicate whether K-Anonymity is enforced for the traffic.
  // By default, this would be false, i.e. K-Anonymity is not enforced.
  bool enforce_kanon = 9;

  // Clients can indicate whether this request can be used for debug.
  // By default, this would be false, i.e. cannot be used for debug.
  // Currently Android request where ad-id is not zeroed out is eligible.
  bool prod_debug = 10;
}

// Grouping of data pertaining to protected app signals.
message ProtectedAppSignals {
  // Raw and system signals from device that can help generate a relevant app
  // install ad for user.
  bytes app_install_signals = 1;

  // Version of the encoding used for the protected app signals.
  int32 encoding_version = 2;
}

// A BuyerInput includes data that a buyer (DSP) requires to generate bids.
message BuyerInput {
  // CustomAudience information passed from the client.
  message CustomAudience {
    reserved 7;

    // Required.
    // Name or tag of Custom Audience.
    string name = 1;

    // Required to trace back to origin of the winner ad
    // NOTE: Corresponds to "origin" on B&A side
    string owner = 8;

    // Required to fetch real time bidding signals from buyer's key/value
    // server.
    repeated string bidding_signals_keys = 2;

    // Optional.
    // Ids of ad_render_urls generated by the DSP / Buyer and passed to the
    // client. Then client passes this in CustomAudience if available.
    // Note: If the Buyer doesn't generate the ad_render_id, then their
    // GenerateBid() should dynamically generate the url for the bid. The
    // winning ad render url returned back to the client will be validated with
    // the Interest Group information on the client.
    repeated string ad_render_ids = 3;

    // Optional.
    // Ids of ad_component_render_url(s) generated by the DSP / Buyer and passed
    // to the client.
    //
    // Note: If the Buyer doesn't generate the ad_component_render_id, device
    // will not pass ads to Bidding and Auction services to ensure payload size
    // is small. In this case, GenerateBid() should dynamically generate the
    // urls for component ads.The winning ad render url returned back to the
    // client will be validated with the Interest Group information on the
    // client.
    repeated string component_ads = 4;

    // Optional.
    // User bidding signal that may be ingested during bidding.
    // This is a JSON array.
    // NOTE: If this is used by the Buyer for bidding, it is recommended to
    // fetch this server side from Buyer Key / Value server to keep request
    // payload size small.
    string user_bidding_signals = 5;

    // Required for bidding.
    // Contains filtering data, like Frequency Cap.
    oneof DeviceSignals {
      // Information passed by Android.
      AndroidSignals android_signals = 6;
    }
  }
  // The Custom Audiences owned by the buyer.
  repeated CustomAudience custom_audiences = 1;

  // Signals from device that can help generate a relevant app install ad for
  // users.
  ProtectedAppSignals protected_app_signals = 2;
}

// Information passed by Android.
message AndroidSignals {}

// Protected Audience auction result returned from SellerFrontEnd to the client
// through the Seller service. It is encrypted by the SellerFrontEnd, passed
// through the untrusted Seller service and decrypted by the client. Note that
// untrusted Seller service will be unable to determine if there was a
// successful auction result, so the client must check the value of is_chaff.
message AuctionResult {
  // The ad that will be rendered on the end user's device.
  string ad_render_url = 1;

  // Render URLs for ads which are components of the main ad.
  repeated string ad_component_render_urls = 2;

  // Name of the Custom Audience, the remarketing ad belongs to.
  string custom_audience_name = 3;

  // Owner of the Custom Audience, the remarketing ad belongs to.
  // NOTE: Corresponds to "origin" on B&A side
  string custom_audience_owner = 13;

  // Domain of the Buyer who owns the winner ad.
  // Note: When compared to B&A this corresponds to interest_group_owner field.
  string buyer = 4;

  // Score of the ad determined during the auction. Any value that is zero or
  // negative indicates that the ad cannot win the auction. The winner of the
  // auction would be the ad that was given the highest score.
  // The output from ScoreAd() script is desirability that implies score for an
  // ad.
  float score = 5;

  // Bid price corresponding to an ad.
  float bid = 6;

  // Boolean to indicate that there is no remarketing winner from the auction.
  // AuctionResult may be ignored by the client (after decryption) if this is
  // set to true.
  bool is_chaff = 7;

  // The reporting urls registered during the execution of reportResult() and
  // reportWin().
  WinReportingUrls win_reporting_urls = 8;

  // Debugging URLs for the Buyer. This information is populated only in case of
  // component auctions.
  DebugReportUrls buyer_debug_report_urls = 9;

  // Debugging URLs for the Seller. This information is populated only in case
  // of component auctions.
  DebugReportUrls seller_debug_report_urls = 10;

  // List of custom audience indices that generated bids.
  message CustomAudienceIndex {
    // List of indices of custom audiences. These indices are derived from the
    // original ProtectedAudienceInput sent from the client.
    repeated int32 index = 1;
  }

  // Map from the buyer participating origin (that participated in the auction)
  // to custom audience indices.
  map<string, CustomAudienceIndex> bidding_groups = 11;

  // In the event of an error during the SelectAd request, an Error object will
  // be returned as a part of the AuctionResult to indicate what went wrong.
  message Error {
    // Status code.
    int32 code = 1;

    // Message containing the failure reason.
    string message = 2;
  }

  // Error thrown during the SelectAd request. If there is no error and the
  // request completes successfully, this field will be empty.
  Error error = 12;

  // Specifies type of the ad. It can help differentiate between ads when
  // B&A is supporting multiple ad targeting use cases concurrently.
  enum AdType {
    UNKNOWN = 0;

    // Remarketing ad.
    REMARKETING_AD = 1;

    // An app install ad.
    APP_INSTALL_AD = 2;
  }

  // Type of the winning ad.
  AdType ad_type = 14;

  message AuctionParams {
    // Component Seller domain.
    // This field is used to tie the auction result to a specific component
    // seller. This field is returned in server orchestrated
    // component and top level auctions.
    // 1. This is returned from a server orchestrated component auction and passed
    // by the top level seller as part of component_auction_results in the top level
    // auction. The top level seller's scoreAd function then receives this as input.
    // 2. This is returned from top level auction conducted using server orchestrated
    // component_auction_results. This is then passed to the device (Android) which
    // uses the field to deduce the winning seller for the SDK.
    string component_seller = 2;
  }

  // This is populated for multi seller auctions.
  AuctionParams auction_params = 18;
}

// The reporting urls registered during the execution of reportResult() and
// reportWin(). These urls will be pined from the client.
message WinReportingUrls {
  message ReportingUrls {
    // The url to be pinged for reporting win to the Buyer or Seller.
    string reporting_url = 1;

    // The map of (interactionKey, URI).
    map<string, string> interaction_reporting_urls = 2;
  }

  // The reporting urls registered during the execution of
  // reportWin(). These urls will be pinged from client.
  ReportingUrls buyer_reporting_urls = 1;

  // The reporting urls registered during the execution of reportResult() of the
  // seller in case of single seller auction and component seller in case of
  // multi seller auctions. These urls will be pinged from client.
  ReportingUrls component_seller_reporting_urls = 2;

  // The reporting urls registered during the execution of reportResult() of the
  // top level seller in case of multi seller auction. These urls will be pinged
  // from client. This will not be set for single seller auctions.
  ReportingUrls top_level_seller_reporting_urls = 3;
}

// Urls to support debug reporting, when auction is won and auction is lost.
message DebugReportUrls {
  // URL to be triggered if the interest group wins the auction.
  // If undefined or malformed url it will be ignored.
  string auction_debug_win_url = 1;

  // URL to be triggered if the interest grou losses the auction.
  // If undefined or malformed url it will be ignored.
  string auction_debug_loss_url = 2;
}

// Consented debugging configuration.
// Example:
// The Chrome browser can set the following two fields:
// 'consentedDebugConfig': {'isConsented': 'true', 'token': 'xxx'}
message ConsentedDebugConfiguration {
  // Whether the request is consented for debugging.
  bool is_consented = 1;

  // The debug token embedded in the request.
  string token = 2;

  // Whether save debug logs in response (only in non_prod)
  bool is_debug_info_in_response = 3;
}

// Context useful for logging and debugging requests.
message LogContext {
  // UUID for the request (as originating from client).
  string generation_id = 1;

  // Adtech debug id that can be used for correlating the request with the
  // adtech. This will contain `buyer_debug_id` when used in context of buyer
  // services and `seller_debug_id` when used in context of seller services.
  string adtech_debug_id = 2;
}

// Protected App Signals ad related data that Buyer adtechs can send via
// contextual path to control which PAS ads participate in the auction.
message ContextualProtectedAppSignalsData {
  // Optional.
  // Raw Ad ids that can be used to lookup signals from the KV server.
  repeated string ad_render_ids = 1;

  // Optional.
  // Bool indicating whether ads should also be fetched from ads retrieval
  // service.
  //
  // If true, the Bidding server will send an Ad fetch request to the
  // Ad retrieval service and the request will contain the list of ad_render_ids
  // as an additional parameter.
  //
  // If false, the ad_render_ids will be sent to the TEE K/V server to fetch
  // the ads related metadata.
  bool fetch_ads_from_retrieval_service = 2;
}

// PAS input per buyer.
message ProtectedAppSignalsBuyerInput {
  ProtectedAppSignals protected_app_signals = 1;

  // Contextual data related to PAS ads.
  ContextualProtectedAppSignalsData contextual_protected_app_signals_data = 2;
}

enum ClientType {
  UNKNOWN = 0;

  // An Android device with Google Mobile Services (GMS).
  // Note: This covers apps on Android and browsers on Android.
  ANDROID = 1;

  // Any browser.
  BROWSER = 2;
}

// GetBidsRequest is sent by the SellerFrontEnd Service to the BuyerFrontEnd
// service.
message GetBidsRequest {
  // Unencrypted request.
  message GetBidsRawRequest {
    // Whether this is a fake request from SellerFrontEnd service
    // and should be dropped.
    // Note: SellerFrontEnd service will send chaffs to a very small set of
    // other buyers not participating in the auction. This is required for
    // privacy reasons to prevent seller from figuring the buyers by observing
    // the network traffic to `BuyerFrontEnd` Services, outside TEE.
    bool is_chaff = 1;

    // Buyer Input for the Buyer that includes keys for Buyer Key Value lookup
    // and other signals for bidding. In the case of is_chaff = true, this will
    // be noise.
    BuyerInput buyer_input = 2;

    // Information about auction (ad format, size) derived contextually.
    // Represents a serialized string that is deserialized to a JSON object
    // before passing to Adtech script. Copied from contextual signals sent to
    // SellerFrontEnd service.
    string auction_signals = 3;

    // Buyer may provide additional contextual information that could help in
    // generating bids. This is Copied from contextual signals sent to
    // SellerFrontEnd service.
    // The value represents a serialized string that is deserialized to a JSON
    // object before passing to Adtech script.
    string buyer_signals = 4;

    // Seller origin.
    // Used to verify that a valid seller is sending the request.
    string seller = 5;

    // Publisher website or app that is part of Buyer KV lookup url.
    string publisher_name = 6;

    // A boolean value which indicates if event level debug reporting should be
    // enabled or disabled for this request.
    bool enable_debug_reporting = 7;

    // Helpful context for logging and tracing the request.
    LogContext log_context = 8;

    // Consented debugging field.
    ConsentedDebugConfiguration consented_debug_config = 9;

    // Protected App signals buyer input.
    ProtectedAppSignalsBuyerInput protected_app_signals_buyer_input = 10;

    // Client device type. Passed to the key/value services.
    ClientType client_type = 11;

    // Top level seller passed in case of component auctions. This is forwarded
    // to generateBid.
    string top_level_seller = 12;

    // Optional.
    // The Id is specified by the buyer to support coordinated experiments
    // with the buyer's Key/Value services.
    optional int32 buyer_kv_experiment_group_id = 13;

    // Optional.
    // A boolean value which indicates whether temporary unlimited egress should
    // be enabled.
    bool enable_unlimited_egress = 14;

    // A limit enforced by sellers on number of bids returned by each
    // generateBid() execution.
    //
    // With K-Anonymity integration, each generateBid() can return multiple
    // bids instead of one, this is referred to as multi-bid generation. This
    // limit is required to enforce a limit with multi-bid generation.
    //
    // For Protected Audience, the limit would be enforced on generateBid()
    // execution per Interest Group.
    // For Protected App Signals (PAS), the limit would be enforced per buyer
    // generateBid() execution.
    //
    // If the seller doesn't set the limit, a default would be set by the
    // Bidding server.
    int32 multi_bid_limit = 15;

    // Clients can indicate whether K-Anonymity is enforced for the traffic.
    // By default, this would be false, i.e. K-Anonymity is not enforced.
    bool enforce_kanon = 16;

    // A boolean value which indicates whether this request can be used for debugging.
    // current eligible request: Android request with ad-id
    bool is_debug_eligible = 17;

    // Optional.
    // Represents a serialized JSON map containing priority signal entries used to
    // construct the priority signals vector.
    string priority_signals = 18;
  }

  // Encrypted GetBidsRawRequest.
  bytes request_ciphertext = 1;

  // Version of the public key used for request encryption. The service
  // needs to use private keys corresponding to same key_id to decrypt
  // 'request_ciphertext'.
  string key_id = 2;
}
