// Copyright 2021 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";

package google.ads.googleads.v7.services;

import "google/ads/googleads/v7/common/criteria.proto";
import "google/ads/googleads/v7/enums/frequency_cap_time_unit.proto";
import "google/ads/googleads/v7/enums/reach_plan_ad_length.proto";
import "google/ads/googleads/v7/enums/reach_plan_age_range.proto";
import "google/ads/googleads/v7/enums/reach_plan_network.proto";
import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";

option csharp_namespace = "Google.Ads.GoogleAds.V7.Services";
option go_package = "google.golang.org/genproto/googleapis/ads/googleads/v7/services;services";
option java_multiple_files = true;
option java_outer_classname = "ReachPlanServiceProto";
option java_package = "com.google.ads.googleads.v7.services";
option objc_class_prefix = "GAA";
option php_namespace = "Google\\Ads\\GoogleAds\\V7\\Services";
option ruby_package = "Google::Ads::GoogleAds::V7::Services";

// Proto file describing the reach plan service.

// Reach Plan Service gives users information about audience size that can
// be reached through advertisement on YouTube. In particular,
// GenerateReachForecast provides estimated number of people of specified
// demographics that can be reached by an ad in a given market by a campaign of
// certain duration with a defined budget.
service ReachPlanService {
  option (google.api.default_host) = "googleads.googleapis.com";
  option (google.api.oauth_scopes) = "https://www.googleapis.com/auth/adwords";

  // Returns the list of plannable locations (for example, countries & DMAs).
  //
  // List of thrown errors:
  //   [AuthenticationError]()
  //   [AuthorizationError]()
  //   [HeaderError]()
  //   [InternalError]()
  //   [QuotaError]()
  //   [RequestError]()
  rpc ListPlannableLocations(ListPlannableLocationsRequest) returns (ListPlannableLocationsResponse) {
    option (google.api.http) = {
      post: "/v7:listPlannableLocations"
      body: "*"
    };
  }

  // Returns the list of per-location plannable YouTube ad formats with allowed
  // targeting.
  //
  // List of thrown errors:
  //   [AuthenticationError]()
  //   [AuthorizationError]()
  //   [HeaderError]()
  //   [InternalError]()
  //   [QuotaError]()
  //   [RequestError]()
  rpc ListPlannableProducts(ListPlannableProductsRequest) returns (ListPlannableProductsResponse) {
    option (google.api.http) = {
      post: "/v7:listPlannableProducts"
      body: "*"
    };
    option (google.api.method_signature) = "plannable_location_id";
  }

  // Generates a product mix ideas given a set of preferences. This method
  // helps the advertiser to obtain a good mix of ad formats and budget
  // allocations based on its preferences.
  //
  // List of thrown errors:
  //   [AuthenticationError]()
  //   [AuthorizationError]()
  //   [HeaderError]()
  //   [InternalError]()
  //   [QuotaError]()
  //   [ReachPlanError]()
  //   [RequestError]()
  rpc GenerateProductMixIdeas(GenerateProductMixIdeasRequest) returns (GenerateProductMixIdeasResponse) {
    option (google.api.http) = {
      post: "/v7/customers/{customer_id=*}:generateProductMixIdeas"
      body: "*"
    };
    option (google.api.method_signature) = "customer_id,plannable_location_id,currency_code,budget_micros";
  }

  // Generates a reach forecast for a given targeting / product mix.
  //
  // List of thrown errors:
  //   [AuthenticationError]()
  //   [AuthorizationError]()
  //   [FieldError]()
  //   [HeaderError]()
  //   [InternalError]()
  //   [QuotaError]()
  //   [RangeError]()
  //   [ReachPlanError]()
  //   [RequestError]()
  rpc GenerateReachForecast(GenerateReachForecastRequest) returns (GenerateReachForecastResponse) {
    option (google.api.http) = {
      post: "/v7/customers/{customer_id=*}:generateReachForecast"
      body: "*"
    };
    option (google.api.method_signature) = "customer_id,campaign_duration,planned_products";
  }
}

// Request message for [ReachPlanService.ListPlannableLocations][google.ads.googleads.v7.services.ReachPlanService.ListPlannableLocations].
message ListPlannableLocationsRequest {

}

// The list of plannable locations.
message ListPlannableLocationsResponse {
  // The list of locations available for planning (Countries, DMAs,
  // sub-countries).
  // For locations like Countries, DMAs see
  // https://developers.google.com/adwords/api/docs/appendix/geotargeting for
  // more information.
  repeated PlannableLocation plannable_locations = 1;
}

// A plannable location: a country, a DMA, a metro region, a tv region,
// a province.
message PlannableLocation {
  // The location identifier.
  optional string id = 4;

  // The unique location name in english.
  optional string name = 5;

  // The parent country code, not present if location is a country.
  // If present will always be a criterion id: additional information, such as
  // country name are returned both via ListPlannableLocations or directly by
  // accessing GeoTargetConstantService with the criterion id.
  optional int64 parent_country_id = 6;
}

// Request to list available products in a given location.
message ListPlannableProductsRequest {
  // Required. The ID of the selected location for planning. To list the available
  // plannable location ids use ListPlannableLocations.
  string plannable_location_id = 2 [(google.api.field_behavior) = REQUIRED];
}

// A response with all available products.
message ListPlannableProductsResponse {
  // The list of products available for planning and related targeting metadata.
  repeated ProductMetadata product_metadata = 1;
}

// The metadata associated with an available plannable product.
message ProductMetadata {
  // The code associated with the ad product. E.g. BUMPER, TRUEVIEW_IN_STREAM
  // To list the available plannable product codes use ListPlannableProducts.
  optional string plannable_product_code = 4;

  // The name associated with the ad product.
  string plannable_product_name = 3;

  // The allowed plannable targeting for this product.
  PlannableTargeting plannable_targeting = 2;
}

// The targeting for which traffic metrics will be reported.
message PlannableTargeting {
  // Allowed plannable age ranges for the product for which metrics will be
  // reported. Actual targeting is computed by mapping this age range onto
  // standard Google common.AgeRangeInfo values.
  repeated google.ads.googleads.v7.enums.ReachPlanAgeRangeEnum.ReachPlanAgeRange age_ranges = 1;

  // Targetable genders for the ad product.
  repeated google.ads.googleads.v7.common.GenderInfo genders = 2;

  // Targetable devices for the ad product.
  repeated google.ads.googleads.v7.common.DeviceInfo devices = 3;

  // Targetable networks for the ad product.
  repeated google.ads.googleads.v7.enums.ReachPlanNetworkEnum.ReachPlanNetwork networks = 4;
}

// Request message for [ReachPlanService.GenerateProductMixIdeas][google.ads.googleads.v7.services.ReachPlanService.GenerateProductMixIdeas].
message GenerateProductMixIdeasRequest {
  // Required. The ID of the customer.
  string customer_id = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The ID of the location, this is one of the ids returned by
  // ListPlannableLocations.
  string plannable_location_id = 6 [(google.api.field_behavior) = REQUIRED];

  // Required. Currency code.
  // Three-character ISO 4217 currency code.
  string currency_code = 7 [(google.api.field_behavior) = REQUIRED];

  // Required. Total budget.
  // Amount in micros. One million is equivalent to one unit.
  int64 budget_micros = 8 [(google.api.field_behavior) = REQUIRED];

  // The preferences of the suggested product mix.
  // An unset preference is interpreted as all possible values are allowed,
  // unless explicitly specified.
  Preferences preferences = 5;
}

// Set of preferences about the planned mix.
message Preferences {
  // True if ad skippable.
  // If not set, default is any value.
  optional bool is_skippable = 6;

  // True if ad start with sound.
  // If not set, default is any value.
  optional bool starts_with_sound = 7;

  // The length of the ad.
  // If not set, default is any value.
  google.ads.googleads.v7.enums.ReachPlanAdLengthEnum.ReachPlanAdLength ad_length = 3;

  // True if ad will only show on the top content.
  // If not set, default is false.
  optional bool top_content_only = 8;

  // True if the price guaranteed. The cost of serving the ad is agreed upfront
  // and not subject to an auction.
  // If not set, default is any value.
  optional bool has_guaranteed_price = 9;
}

// The suggested product mix.
message GenerateProductMixIdeasResponse {
  // A list of products (ad formats) and the associated budget allocation idea.
  repeated ProductAllocation product_allocation = 1;
}

// An allocation of a part of the budget on a given product.
message ProductAllocation {
  // Selected product for planning. The product codes returned are within the
  // set of the ones returned by ListPlannableProducts when using the same
  // location id.
  optional string plannable_product_code = 3;

  // The value to be allocated for the suggested product in requested currency.
  // Amount in micros. One million is equivalent to one unit.
  optional int64 budget_micros = 4;
}

// Request message for [ReachPlanService.GenerateReachForecast][google.ads.googleads.v7.services.ReachPlanService.GenerateReachForecast].
message GenerateReachForecastRequest {
  // Required. The ID of the customer.
  string customer_id = 1 [(google.api.field_behavior) = REQUIRED];

  // The currency code.
  // Three-character ISO 4217 currency code.
  optional string currency_code = 9;

  // Required. Campaign duration.
  CampaignDuration campaign_duration = 3 [(google.api.field_behavior) = REQUIRED];

  // Desired cookie frequency cap that will be applied to each planned product.
  // This is equivalent to the frequency cap exposed in Google Ads when creating
  // a campaign, it represents the maximum number of times an ad can be shown to
  // the same user.
  // If not specified no cap is applied.
  //
  // This field is deprecated in v4 and will eventually be removed.
  // Please use cookie_frequency_cap_setting instead.
  optional int32 cookie_frequency_cap = 10;

  // Desired cookie frequency cap that will be applied to each planned product.
  // This is equivalent to the frequency cap exposed in Google Ads when creating
  // a campaign, it represents the maximum number of times an ad can be shown to
  // the same user during a specified time interval.
  // If not specified, no cap is applied.
  //
  // This field replaces the deprecated cookie_frequency_cap field.
  FrequencyCap cookie_frequency_cap_setting = 8;

  // Desired minimum effective frequency (the number of times a person was
  // exposed to the ad) for the reported reach metrics [1-10].
  // This won't affect the targeting, but just the reporting.
  // If not specified, a default of 1 is applied.
  optional int32 min_effective_frequency = 11;

  // The targeting to be applied to all products selected in the product mix.
  //
  // This is planned targeting: execution details might vary based on the
  // advertising product, please consult an implementation specialist.
  //
  // See specific metrics for details on how targeting affects them.
  //
  // In some cases, targeting may be overridden using the
  // PlannedProduct.advanced_product_targeting field.
  Targeting targeting = 6;

  // Required. The products to be forecast.
  // The max number of allowed planned products is 15.
  repeated PlannedProduct planned_products = 7 [(google.api.field_behavior) = REQUIRED];
}

// A rule specifying the maximum number of times an ad can be shown to a user
// over a particular time period.
message FrequencyCap {
  // Required. The number of impressions, inclusive.
  int32 impressions = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. The type of time unit.
  google.ads.googleads.v7.enums.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit time_unit = 2 [(google.api.field_behavior) = REQUIRED];
}

// The targeting for which traffic metrics will be reported.
message Targeting {
  // Required. The ID of the selected location.
  // Plannable locations ID can be obtained from ListPlannableLocations.
  optional string plannable_location_id = 6;

  // Targeted age range.
  // If not specified, targets all age ranges.
  google.ads.googleads.v7.enums.ReachPlanAgeRangeEnum.ReachPlanAgeRange age_range = 2;

  // Targeted genders.
  // If not specified, targets all genders.
  repeated google.ads.googleads.v7.common.GenderInfo genders = 3;

  // Targeted devices.
  // If not specified, targets all applicable devices. Applicable devices vary
  // by product and region and can be obtained from ListPlannableProducts.
  repeated google.ads.googleads.v7.common.DeviceInfo devices = 4;

  // Targetable network for the ad product.
  // If not specified, targets all applicable networks. Applicable networks vary
  // by product and region and can be obtained from ListPlannableProducts.
  google.ads.googleads.v7.enums.ReachPlanNetworkEnum.ReachPlanNetwork network = 5;
}

// The duration of a planned campaign.
message CampaignDuration {
  // The duration value in days.
  optional int32 duration_in_days = 2;
}

// A product being planned for reach.
message PlannedProduct {
  // Required. Selected product for planning.
  // The code associated with the ad product. E.g. Trueview, Bumper
  // To list the available plannable product codes use ListPlannableProducts.
  optional string plannable_product_code = 3;

  // Required. Maximum budget allocation in micros for the selected product.
  // The value is specified in the selected planning currency_code.
  // E.g. 1 000 000$ = 1 000 000 000 000 micros.
  optional int64 budget_micros = 4;
}

// Response message containing the generated reach curve.
message GenerateReachForecastResponse {
  // Reference on target audiences for this curve.
  OnTargetAudienceMetrics on_target_audience_metrics = 1;

  // The generated reach curve for the planned product mix.
  ReachCurve reach_curve = 2;
}

// The reach curve for the planned products.
message ReachCurve {
  // All points on the reach curve.
  repeated ReachForecast reach_forecasts = 1;
}

// A point on reach curve.
message ReachForecast {
  // The cost in micros.
  int64 cost_micros = 5;

  // Forecasted traffic metrics for this point.
  Forecast forecast = 2;

  // The forecasted allocation and traffic metrics for each planned product
  // at this point on the reach curve.
  repeated PlannedProductReachForecast planned_product_reach_forecasts = 4;
}

// Forecasted traffic metrics for the planned products and targeting.
message Forecast {
  // Number of unique people reached at least
  // GenerateReachForecastRequest.min_effective_frequency times that exactly
  // matches the Targeting.
  optional int64 on_target_reach = 5;

  // Total number of unique people reached at least
  // GenerateReachForecastRequest.min_effective_frequency times. This includes
  // people that may fall outside the specified Targeting.
  optional int64 total_reach = 6;

  // Number of ad impressions that exactly matches the Targeting.
  optional int64 on_target_impressions = 7;

  // Total number of ad impressions. This includes impressions that may fall
  // outside the specified Targeting, due to insufficient information on
  // signed-in users.
  optional int64 total_impressions = 8;

  // Number of times the ad's impressions were considered viewable.
  // See https://support.google.com/google-ads/answer/7029393 for
  // more information about what makes an ad viewable and how
  // viewability is measured.
  optional int64 viewable_impressions = 9;
}

// The forecasted allocation and traffic metrics for a specific product
// at a point on the reach curve.
message PlannedProductReachForecast {
  // Selected product for planning. The product codes returned are within the
  // set of the ones returned by ListPlannableProducts when using the same
  // location id.
  string plannable_product_code = 1;

  // The cost in micros. This may differ from the product's input allocation
  // if one or more planned products cannot fulfill the budget because of
  // limited inventory.
  int64 cost_micros = 2;

  // Forecasted traffic metrics for this product.
  PlannedProductForecast planned_product_forecast = 3;
}

// Forecasted traffic metrics for a planned product.
message PlannedProductForecast {
  // Number of unique people reached that exactly matches the Targeting.
  int64 on_target_reach = 1;

  // Number of unique people reached. This includes people that may fall
  // outside the specified Targeting.
  int64 total_reach = 2;

  // Number of ad impressions that exactly matches the Targeting.
  int64 on_target_impressions = 3;

  // Total number of ad impressions. This includes impressions that may fall
  // outside the specified Targeting, due to insufficient information on
  // signed-in users.
  int64 total_impressions = 4;

  // Number of times the ad's impressions were considered viewable.
  // See https://support.google.com/google-ads/answer/7029393 for
  // more information about what makes an ad viewable and how
  // viewability is measured.
  optional int64 viewable_impressions = 5;
}

// Audience metrics for the planned products.
// These metrics consider the following targeting dimensions:
//
// - Location
// - PlannableAgeRange
// - Gender
message OnTargetAudienceMetrics {
  // Reference audience size matching the considered targeting for YouTube.
  optional int64 youtube_audience_size = 3;

  // Reference audience size matching the considered targeting for Census.
  optional int64 census_audience_size = 4;
}
