// Copyright 2014, Beeswax.IO Inc.
// Author: ramr@beeswax.com
//
// Beeswax extensions to the OpenRTB spec.
// These extensions are specific to Beeswax and are not a part of
// the OpenRTB spec.
// All OpenRTB message objects are extended using
// an optional Extension message named 'ext'

syntax = "proto2";
package openrtb;

option java_package = "com.beeswax.openrtb";

import "beeswax/base/eventid.proto";
import "beeswax/openrtb/openrtb_common.proto";
import "beeswax/openrtb/seat_constraints.proto";

// Next available tag: 5
// Refer to the documentation of BuyerPricingRule in adx.proto
// to understand the meaning of these fields.
message AdvertiserInfo {
  repeated int64 included_advertisers = 1;
  repeated int64 excluded_advertisers = 2;
  optional bool blocked = 3;
  // CPM micros in buyer currency i.e. USD
  optional int64 minimum_cpm_micros = 4;
}

// Next available tag: 3
// Used to represent <w,h> at various places in the
// extensions.
// For e.g. Additional ad sizes supported on an adslot.
message Dimension {
  optional int32 width = 1;
  optional int32 height = 2;
}

// Next available tag: 15
message BidRequestExtensions {
  optional Enums.Inventory.Source inventory_source = 1;
  optional base.EventId auction_id = 2;
  // The unique identifier of the auction per buzz_key.
  // Format: <auctionid.timestamp>.<auctionid.hostid>.<auctionid.tid>.<auctionid.imp_idx>.<buzz_key>
  // imp_idx: currently is present iff more than one impressions are present in the original exchange bid request.
  // auction_id_str: contains buzz_key so it is populated in sbs.
  optional string auctionid_str = 8;

  // The unique identifier for the exchange bid request per buzz_key.
  // Format: <auctionid.timestamp>.<auctionid.hostid>.<auctionid.tid>.<buzz_key>
  // request_id_str contains buzz_key so it is populated in sbs.
  optional string requestid_str = 14;

  // This is slated to be removed. It is a typo.
  optional string request_id_str = 13 [deprecated = true];

  // This field is used for Geo targeting.
  // It is populated by the LocalAugmentor in Stinger.
  optional TargetingGeoExtension targeting_geo = 3;

  // time_of_week is a stinger calculated field used for targetting
  optional int32 time_of_week = 4;

  // Used to identify Stinger.
  optional string buzz_key = 5;

  // Next available tag: 3
  message AugmentorData {

    // Next available tag: 3
    // Segment along with augmentor's ID allows augmentor based targeting
    message Segment {
      // ID of a augmentor’s segment
      optional string id = 1;

      // String representing the value of the segment.
      optional string value = 2;
    }

    // Augmentor identifier, used for targeting
    optional string id = 1;

    // Array of Augmentor segments
    repeated Segment segment = 2;
  }

  // This field is used by Augmentors like ManagedListAugmentor
  repeated AugmentorData augmentor_data = 6;

  // Determines how impression notifications will happen for this request. See
  // ImpressionTracker comments for more information.
  optional Enums.Inventory.ImpressionTracker imp_tracker = 10;

  // Determines how supplier click tracking will happen for this request. See
  // SupplierClickTracker for more information.
  optional Enums.Inventory.SupplierClickTracker supplier_click_tracker = 11;

  // Exchange specific extensions
  optional AppNexusBidRequestExtension appnexus = 7;
  optional AdxBidRequestExtension adx = 9;

  enum AdsTxtStatus {
    UNKNOWN = -1;
    // The request does not contain a domain, either because it is not a web request (ie it is an
    // app or native request) or it is a web request but does not contain a domain. Since it doesn't
    // have a domain, we cannot check it's Ads.txt status.
    NO_DOMAIN = 0;
    // The request's domain does not have an Ads.txt file
    NO_ADS_TXT_FILE = 1;
    // We have not looked up the Ads.txt file for the request's domain
    ADS_TXT_NOT_SCANNED = 2;
    // The request's domain does not allow any advertising
    NO_ADVERTISING_ALLOWED = 3;
    // The request is missing a publisher id so we cannot check its Ads.txt status
    MISSING_PUB_ID = 4;
    // The request's domain does have an Ads.txt file, but it does not allow advertising from this
    // exchange / publisher ID combination
    NOT_AUTH = 5;
    // The domain's Ads.txt file allows this exchange / publisher ID to resell advertising
    AUTH_RESELLER = 6;
    // The domain's Ads.txt file allows this exchange / publisher ID to advertise directly
    AUTH_DIRECT = 7;
  }
  optional AdsTxtStatus ads_txt = 12;

  extensions 1000 to max;
}


// Next available tag: 12
message ImpressionExtensions {
  optional Enums.Inventory.PlacementType placement_type = 2;
  optional Enums.Inventory.EnvironmentType environment_type = 3;
  repeated string placements = 5;
  repeated AdvertiserInfo advertiser_info = 4;

  optional ViewabilityExtensions viewability = 8;

  // Seat ids that the exchange considers eligible to serve on this impression.
  // This feature is currently only supported by Adx.
  repeated string eligible_seat_ids = 7;

  optional SeatConstraintsExtension seat_constraints = 11;

  // Exchange specific extensions
  optional AdxImpressionExtension adx = 1;

  // allowed restricted ad categories for ADX
  repeated int32 allowed_restricted_category = 9 [packed=true];
  repeated int32 allowed_restricted_category_for_deals = 10 [packed=true];

  extensions 1000 to max;

  // Deprecated field. Use ViewabilityExtensions field instead.
  optional float exchange_predicted_view_rate = 6 [deprecated = true];
}

// Next available tag: 5
message BannerExtensions {
  // Blocked ApiFrameworks
  repeated Enums.BidRequest.Impression.ApiFramework bapis = 1;

  // Creative attributes that are required by the request.
  // For e.g. MoPub request have "AD_HAS_THUMBNAIL" for the creative
  //          to be returned in the response
  repeated CreativeAttribute required_attrs = 2;

  // Some exchanges such as Google Adx support multiple allowed sizes for
  // an impression.
  // In such cases, the additional dimensions (w, h) that are supported
  // are present in this field.
  // For example, if Adx supports 5 sets of allowed sizes in a request.
  // The first allowed size will be in banner.w and banner.h
  // The additional 4 sets will be in this field.
  repeated Dimension additional_dimensions = 3;

  // Some exchanges support "rewarded banners". This signifies that an end user
  // will recieve a reward for interacting with the ad. E.g. if the user plays
  // a game in a playable banner, they get game currency in a phone game.
  //
  // Two things to note:
  //   1. Protobufs sets bools false by default. Unless this field exists and
  //      is explicitly set to true, a banner is considered "nonrewarded".
  //   2. No exchange actually defines this field here, it is a generalization
  //      of the different ways that exchanges denote rewarded banners.
  optional bool rewarded = 4;

  extensions 1000 to max;
}


// Next available tag: 6
message VideoExtensions {
  // player_size can be one of ["S", "M"., "L", "XL", "NA"].
  // Added by augmentor in Beeswax Front End Server (FES)
  optional string player_size = 1;

  // Creative attributes that are required by the request.
  // For e.g. Adx requests that require skippable ads are modeled
  // as having required_attr = AD_CAN_BE_SKIPPED
  repeated CreativeAttribute required_attrs = 2;

  enum PlacementType {
    IN_BANNER = 0;
    IN_STREAM = 1;
  }
  optional PlacementType placement_type = 3 [default = IN_STREAM];

  // Number of seconds into the video ad when the skip button appears.
  // This is only applicable to skippable video ads.
  // Some inventory sources such as Google Ad Exchange do not specify
  // this skip offset explicity in the bid request.
  // For such sources, skip_offset of 5 seconds is a safe default.
  optional int32 skip_offset = 4 [default = 5];

  // Some exchanges support "rewarded videos". This signifies that an end user
  // will recieve a reward for interacting with the ad. E.g. if the user watches
  // the whole video, they get game currency in a phone game.
  //
  // Two things to note:
  //   1. Protobufs sets bools false by default. Unless this field exists and
  //      is explicitly set to true, a video is considered "nonrewarded".
  //   2. No exchange actually defines this field here, it is a generalization
  //      of the different ways that exchanges denote rewarded videos.
  optional bool rewarded = 5;

  extensions 1000 to max;
}

// Next available tag: 2
message NativeExtensions {
  // Exchange specific extensions
  optional SamsungNativeExtension samsung = 1;
  extensions 1000 to max;
}

message PMPExtensions {
  extensions 1000 to max;
}

// Next available tag: 2
message DirectDealExtensions {
  // Exchange specific extensions
  optional AdxDirectDealExtension adx = 1;
  extensions 1000 to max;
}

message SiteExtensions {
  extensions 1000 to max;
}

message AppExtensions {
  extensions 1000 to max;
}

message ContentExtensions {
  extensions 1000 to max;
}


message ProducerExtensions {
  extensions 1000 to max;
}

// Next available tag: 13
// Tag 1: idfa - Deprecated. Do not resuse.
message DeviceExtensions {
  // Device screen size. Valid values are "S", "M", "L", "XL", and "NA"
  // Added by augmentor in Beeswax Front End Server (FES)
  optional string augmented_device_screen_size = 2 [default = "NA"];

  // Added by augmentor in Beeswax Front End Server (FES)
  optional string augmented_browser = 3 [default = "-1"];

  // Added by augmentor in Beeswax Front End Server (FES)
  optional string augmented_browser_version = 4 [default = "-1"];

  // Added by augmentor in Beeswax Front End Server (FES)
  optional string augmented_os = 5 [default = "-1"];

  // Added by augmentor in Beeswax Front End Server (FES)
  optional string augmented_osv = 6 [default = "-1"];

  // Added by augmentor in Beeswax Front End Server (FES)
  optional string augmented_model = 7 [default = "-1"];

  // Added by augmentor in Beeswax Front End Server (FES)
  optional string augmented_make = 8 [default = "-1"];

  // Added by augmentor in Beeswax Front End Server (FES)
  optional Enums.BidRequest.Device.DeviceType augmented_devicetype = 9 [default = UNKNOWN];

  // Added by augmentor in Beeswax Front End Server (FES)
  optional string augmented_carrier = 10;

  // GDPR-compliant hashed ip
  optional string ip_hashed = 11;

  // GDPR-compliant hashed ipv6
  optional string ipv6_hashed = 12;

  extensions 1000 to max;
}

// Next available tag: 9
message UserExtensions {
  // This field identifies the user of the bid request. It will be used
  // for user segment lookup and frequency cap.
  // For WEB request, its value is bito_id (user.id).
  // For APP request, its value is the first field which has value
  // in the following order:
  // device.ifa -> device.dpidsha1 -> device.dpidmd5
  // And the value is prefixed with the names in Enum.Bidrequest.User.UserIdType
  // (Except bito_id - we still use bito as prefix)
  optional string user_id = 1;
  optional Enums.BidRequest.User.UserIdType user_id_type = 2;

  // Next available tag: 3
  message MatchedUserGroups {
    repeated string matched_user_ids = 1;
    optional string partner_handle = 2;
  }
  repeated MatchedUserGroups matched_user_groups = 4;

  // Number of days since the user cookie has been dropped, for example, 10
  optional int32 cookie_age = 3;
  // GDPR-compliant hashed user_id
  optional string user_id_hashed = 8;
  extensions 1000 to max;
}

message PublisherExtensions {
  extensions 1000 to max;
}

// Next available tag: 3
message GeoExtensions {
  optional AdxGeoExtension adx = 1;
  // All granularities of regions in ISO 3166-2.
  repeated string regions = 2;
  extensions 1000 to max;
}

// Next available tag: 2
message DataExtensions {
  optional bool beeswax_augmented = 1 [default = false];
  extensions 1000 to max;
}

message SegmentExtensions {
  extensions 1000 to max;
}

message RegulationsExtensions {
  // When this field is set to true, it implies that Beeswax has determined that
  // this request needs to comply with the GDPR terms and conditions.
  optional Flag gdpr = 1;
  // The raw IAB consent string or "daisybit" as provided in the incoming bid
  // request.
  optional string gdpr_consent_string = 2;
  extensions 1000 to max;
}

message BidResponseExtensions {
  extensions 1000 to max;
}

message SeatBidExtensions {
  extensions 1000 to max;
}

// Next available tag: 11
message BidExtensions {
  extensions 1000 to max;
}


// This field is used for Geo targeting.
// It is populated by the LocalAugmentor in Stinger.
message TargetingGeoExtension {
  // Country using ISO-3166-1 Alpha-3.
  optional string country = 1 [default = "000"];
  // Region using ISO 3166-2
  optional string region = 2 [default = "000/00", deprecated = true];
  // All granularities of regions in ISO 3166-2. If it is empty, "000/00" should
  // be used as the targeting key.
  repeated string regions = 10;
  // City using United Nations Code for Trade and Transport Locations
  // (http://www.unece.org/cefact/locode/service/location.htm).
  optional string city = 3 [default = "-1"];
  // Zip/postal code.
  optional string zip = 4 [default = "-1"];
  optional string metro = 5 [default = "000"];
  optional bool lat_long_present = 6 [default = false];
  optional double lat = 7;
  optional double lon = 8;
  optional Enums.BidRequest.Geo.LocationType type = 9;
}

// Viewability.predicted_viewability is populated by FES LocalAugmentor
// and used for targeting in Matcher
message ViewabilityExtensions {
  // Specifies the predicted viewability from Beeswax ViewabilityPredictor
  optional float predicted_viewability = 1;
  // Specifies the probability that the impression will be viewable by the user,
  // based on historical data.
  // Currently populated for AppNexus and AdX only
  optional float exchange_predicted_view_rate = 2;
}

// Exchange specific extensions.
// Next available tag: 3
message AdxBidRequestExtension {
  // If true, then the selective callout model predicted that we will not bid
  // on this request. ADX sends a sampled percentage of such requests so that they
  // can automatically update the model when bidding patterns change.
  optional bool is_predicted_to_be_ignored = 1;
  // The offset of the user's time from GMT in minutes.
  // For example, GMT-5 is timezone_offset = -300.
  optional int32 timezone_offset = 2;
}

// Next available tag: 2
message AdxDirectDealExtension {
  optional bool publisher_blocks_overridden = 1 [default = false];
}

// Next available tag: 5
message AdxImpressionExtension {
  optional int32 adslot_id = 1;
  // Historical click-through rate for ads served in the ad slot. This is
  // expressed as a fraction in the range [0.0, 1.0]. The default value of
  // -1.0 indicates that historical click-through rate data is not available.
  // This figure does not include data aggregated from AdWords.
  optional float click_through_rate = 2 [default = -1.0];
  repeated int32 allowed_vendor_type = 3;
  // This field will be populated and effective when regs.ext.gdpr is YES.
  repeated int64 consented_providers = 4;
}

// Next available tag: 2
message SamsungNativeExtension {
  optional string native = 1;
}

message AdxGeoExtension {
  optional int32 dma_region_code = 1;
  // Use fes.exchange.adx.AdxBidRequest.HyperlocalSet to parse.
  optional bytes hyperlocal_set = 2;
}

// 2. AppNexus Exchange
// Next available tag: 2
message AppNexusBidRequestExtension {
  // Specifies the ID of the member selling the inventory.
  optional int32 seller_member_id = 1;
}

// Next available tag: 3
message SeatConstraintsExtension {
  // Constraints for a customer's default seat on this exchange if it exists. It
  // is valid for there to be no constraints here. That generally means we are
  // falling back to global auction values, e.g. imp.bid_floor.
  optional openrtb.SeatConstraints default_seat_constraint = 1;
  // A map from Beeswax account_id to SeatConstraint. This is used when seat
  // level information needs to be taken into account during the bidding
  // process. We associate each seat constraint with a Beeswax account_id for
  // ease of lookup during the bidding process. Only accounts that have
  // constraints for a given request will be populated in this map. These values
  // supercede any constraints found in default_seat_constraint.
  map<uint64, openrtb.SeatConstraints> account_seat_constraints = 2;
}