// Copyright 2015, Beeswax.IO Inc.
//
// Adcandidate represents a line item (along with its attributes) that
// is eligible to serve on a given bid request.
// Stinger determines the eligible line items and creatives and generates
// the adcandidate.

syntax = "proto2";
package bid;

import "beeswax/currency/currency.proto";

option java_package = "com.beeswax.bid";

// Bidding agents can implement flexible bidding strategies.
// A bidding strategy consists of attributes that are used by the bidding agent
// at run time to compute the bid.
// CPM, CPC and custom bidding strategies are currently available.
//
// All price information is represented as micros which is the actual value
// multiplied by 1 million i.e. 10e+6.
// The currency used for all fields is specified in the `currency` field,
// which is set per campaign in buzz.
//

// Next Tag: 8
message Bidding {
  // CPM: Always bid a flat price on all matched requests.
  message CpmStrategy {
    optional uint64 flat_bid_micros = 1;
  }
  // CPC: Optimize towards a cost per click goal.
  message CpcStrategy {
    // Deprecated, use Bidding.max_bid_micros instead.
    optional uint64 max_bid_micros = 1 [deprecated = true];
    optional uint64 ecpc_target_micros = 2;
  }
  // Custom strategy is defined using Buzz API.
  // Customers can define many different strategies and identify them using
  // a name.
  // Further, customers can associate multiple key, values with a strategy
  // that are made available in the matching Adcandidate.
  // Customers can use the key,values to implement their own optimization.
  message CustomStrategy {
    optional string name = 1;
    message Params {
      optional string key = 1;
      optional string value = 2;
    }
    repeated Params custom_params = 2;
  }

  // Only one of the strategies will be present.
  optional CpmStrategy cpm_strategy = 1;
  optional CpcStrategy cpc_strategy = 2;
  optional CustomStrategy custom_strategy = 4;
  optional currency.Currency.Code currency = 5;
  // The product of all eligible modifiers' multipliers.
  optional float bid_modifier_multipliers_product = 6 [default = 1.0];
  optional uint64 max_bid_micros = 7;
  // The following fields are for internal use by the bidding agents and
  // will not be set in the request or response.
  optional uint64 bid_price_micros = 3;
}

// Pacing determines the rate of spend of the budget for a line item.
// When pace_delivery is set to true, the bidding agent is expected to pace
// the spend of the line item uniformly over its life time.
//
// Next Tag: 2
message Pacing {
  optional bool pace_delivery = 1 [default = false];
}

// FrequencyCapsInfo contains the information of a lineitem/campaign's
// frequency cap constraints and the user's impression history.
// The bidding agent will not receive adcandidates which are not
// eligible to bid when any of the lineitem/campaingn's frequency cap's
// limit is hit.
//
// Next Id: 4
message FrequencyCapsInfo {
  // FrequencyCap contains the frequency constraints for a given user to not
  // view the ad more than `max_impressions` times within a duration of
  // `duration_seconds`, and the actual impression counts within the duration
  // for the user as in `current_impression_count`.
  // `max_impressions` and `duration_seconds` are defined using Buzz API, and
  // `current_impression_count` is populated real-time per request.
  // E.g. If a line item specifies hourly frequency cap
  // constraints of 10 impression/user, and it has had impressions for the
  // past hour, the value will be
  // {max_impressions = 10, duration_secs = 3600, current_impression_count = 2}.
  //
  //
  // Next Id: 4
  message FrequencyCap {
    // Allowed number of impressions in the duration .
    optional uint32 max_impressions = 1;
    // The duration (in second) in which max_impressions should not be exceeded.
    optional uint32 duration_seconds = 2;
    // Actual impression numbers served in the duration.
    optional uint32 current_impression_count = 3;
  }
  repeated FrequencyCap frequency_cap = 1;
  repeated uint32 imp_timestamps = 2 [deprecated = true];
  // The last rx timestamp in seconds when the ad was served for the
  // line_item/campaign and user combination in the past 30 days. It is
  // updated real-time per request. It will not be populated if the
  // line_item/campaign does not have any impression for the user in the past
  // 30 days.
  optional uint32 last_imp_timestamp = 3;
}

// VendorFeesInfo contains the aggregrated amount and percent of a
// lineitem/campaign's vendor fees.
// Next Id: 3
message VendorFeesInfo {
  // total_vendor_fees_transactions are grouped by currency.
  // vendor fees with the same currency are aggregrated into one
  // CurrencyTransaction object.
  // For example, if a lineitem/campaign has a vendor fees of 30 micros USD,
  // another of 20 micros USD, the other 40 micros GBP,
  // there will be two items in this field - one 50 micros USD,
  // the other 40 micros GBP. (CurrencyTransaction contains the real-time
  //conversion rate)
  // In rare conditions when currency conversion rate is not available,
  // total_vendor_fees_transactions.rate field will not be populated.
  repeated currency.CurrencyTransaction total_vendor_fees_transactions = 1;
  // total_fee_percent_micros is the sum of percent value in micros of all
  // percent type vendor fees.
  // For example, a line/campaign has a vendor fees at 5%, another 2%,
  // this field will be "7" in micros, i.e., 7000000
  optional int64 total_fee_percent_micros = 2;
}

// Adcandidate represents an eligible line item and its attributes.
// Stinger determines the eligible line items for a given request.
//
// Next Tag: 14
message Adcandidate {
  optional uint64 line_item_id = 1;
  optional uint64 campaign_id = 5;
  optional uint64 account_id = 6;
  optional uint64 advertiser_id = 8;
  optional string line_item_alternative_id = 9;
  optional string buzz_key = 7;
  repeated uint64 creative_ids = 2;
  optional Bidding bidding = 3;
  optional Pacing pacing = 4;
  // This field wil be empty if the line_item does not have any frequency
  // cap associated with it.
  optional FrequencyCapsInfo line_item_frequency_caps_info = 10;
  // This field wil be empty if the campaign does not have any frequency
  // cap associated with it.
  optional FrequencyCapsInfo campaign_frequency_caps_info = 11;
  optional VendorFeesInfo line_item_vendor_fees_info = 12;
  optional VendorFeesInfo campaign_vendor_fees_info = 13;
}
