// Copyright 2023 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.v16.services;

import "google/ads/googleads/v16/common/criteria.proto";
import "google/ads/googleads/v16/common/dates.proto";
import "google/ads/googleads/v16/enums/frequency_cap_time_unit.proto";
import "google/ads/googleads/v16/enums/reach_plan_age_range.proto";
import "google/ads/googleads/v16/enums/reach_plan_network.proto";
import "google/ads/googleads/v16/enums/reach_plan_surface.proto";
import "google/ads/googleads/v16/enums/target_frequency_time_unit.proto";
import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";

option csharp_namespace = "Google.Ads.GoogleAds.V16.Services";
option go_package = "google.golang.org/genproto/googleapis/ads/googleads/v16/services;services";
option java_multiple_files = true;
option java_outer_classname = "ReachPlanServiceProto";
option java_package = "com.google.ads.googleads.v16.services";
option objc_class_prefix = "GAA";
option php_namespace = "Google\\Ads\\GoogleAds\\V16\\Services";
option ruby_package = "Google::Ads::GoogleAds::V16::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).
  //
  // List of thrown errors:
  //   [AuthenticationError]()
  //   [AuthorizationError]()
  //   [HeaderError]()
  //   [InternalError]()
  //   [QuotaError]()
  //   [RequestError]()
  rpc ListPlannableLocations(ListPlannableLocationsRequest)
      returns (ListPlannableLocationsResponse) {
    option (google.api.http) = {
      post: "/v16: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: "/v16:listPlannableProducts"
      body: "*"
    };
    option (google.api.method_signature) = "plannable_location_id";
  }

  // 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: "/v16/customers/{customer_id=*}:generateReachForecast"
      body: "*"
    };
    option (google.api.method_signature) =
        "customer_id,campaign_duration,planned_products";
  }
}

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

// The list of plannable locations.
message ListPlannableLocationsResponse {
  // The list of locations available for planning.
  // See
  // https://developers.google.com/google-ads/api/reference/data/geotargets
  // for sample locations.
  repeated PlannableLocation plannable_locations = 1;
}

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

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

  // The parent country (not present if location is a country).
  // If present, will always be a GeoTargetConstant ID. Additional information
  // such as country name is provided by
  // [ReachPlanService.ListPlannableLocations][google.ads.googleads.v16.services.ReachPlanService.ListPlannableLocations]
  // or GoogleAdsService.Search/SearchStream.
  optional int64 parent_country_id = 6;

  // The ISO-3166-1 alpha-2 country code that is associated with the location.
  optional string country_code = 7;

  // The location's type. Location types correspond to target_type returned by
  // searching location type in GoogleAdsService.Search/SearchStream.
  optional string location_type = 8;
}

// 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
  // [ReachPlanService.ListPlannableLocations][google.ads.googleads.v16.services.ReachPlanService.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 (for example: BUMPER,
  // TRUEVIEW_IN_STREAM).
  // To list the available plannable product codes use
  // [ReachPlanService.ListPlannableProducts][google.ads.googleads.v16.services.ReachPlanService.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.v16.enums.ReachPlanAgeRangeEnum.ReachPlanAgeRange
          age_ranges = 1;

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

  // Targetable devices for the ad product.
  // TABLET device targeting is automatically applied to reported metrics
  // when MOBILE targeting is selected for CPM_MASTHEAD,
  // GOOGLE_PREFERRED_BUMPER, and GOOGLE_PREFERRED_SHORT products.
  repeated google.ads.googleads.v16.common.DeviceInfo devices = 3;

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

  // Targetable YouTube Select Lineups for the ad product.
  repeated YouTubeSelectLineUp youtube_select_lineups = 5;

  // Targetable surface combinations for the ad product.
  SurfaceTargetingCombinations surface_targeting = 6;
}

// Request message for
// [ReachPlanService.GenerateReachForecast][google.ads.googleads.v16.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];

  // Chosen cookie frequency cap to 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.
  // Use cookie_frequency_cap_setting instead.
  optional int32 cookie_frequency_cap = 10;

  // Chosen cookie frequency cap to 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, a default of 0 (no cap) is applied.
  //
  // This field replaces the deprecated cookie_frequency_cap field.
  FrequencyCap cookie_frequency_cap_setting = 8;

  // Chosen 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.
  //
  // This field cannot be combined with the effective_frequency_limit field.
  optional int32 min_effective_frequency = 11;

  // The highest minimum effective frequency (the number of times a person was
  // exposed to the ad) value [1-10] to include in
  // Forecast.effective_frequency_breakdowns.
  // If not specified, Forecast.effective_frequency_breakdowns will not be
  // provided.
  //
  // The effective frequency value provided here will also be used as the
  // minimum effective frequency for the reported reach metrics.
  //
  // This field cannot be combined with the min_effective_frequency field.
  optional EffectiveFrequencyLimit effective_frequency_limit = 12;

  // 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, consult an implementation specialist.
  //
  // See specific metrics for details on how targeting affects them.
  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];

  // Controls the forecast metrics returned in the response.
  ForecastMetricOptions forecast_metric_options = 13;

  // The name of the customer being planned for. This is a user-defined value.
  optional string customer_reach_group = 14;
}

// Effective frequency limit.
message EffectiveFrequencyLimit {
  // The highest effective frequency value to include in
  // Forecast.effective_frequency_breakdowns.
  // This field supports frequencies 1-10, inclusive.
  int32 effective_frequency_breakdown_limit = 1;
}

// 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.v16.enums.FrequencyCapTimeUnitEnum.FrequencyCapTimeUnit
      time_unit = 2 [(google.api.field_behavior) = REQUIRED];
}

// The targeting for which traffic metrics will be reported.
message Targeting {
  // The ID of the selected location. Plannable location IDs can be
  // obtained from
  // [ReachPlanService.ListPlannableLocations][google.ads.googleads.v16.services.ReachPlanService.ListPlannableLocations].
  //
  // Requests must set either this field or `plannable_location_ids`.
  //
  // This field is deprecated as of V12 and will be removed in a future release.
  // Use `plannable_location_ids` instead.
  optional string plannable_location_id = 6;

  // The list of plannable location IDs to target with this forecast.
  //
  // If more than one ID is provided, all IDs must have the same
  // `parent_country_id`. Planning for more than `parent_county` is not
  // supported. Plannable location IDs and their `parent_country_id` can be
  // obtained from
  // [ReachPlanService.ListPlannableLocations][google.ads.googleads.v16.services.ReachPlanService.ListPlannableLocations].
  //
  // Requests must set either this field or `plannable_location_id`.
  repeated string plannable_location_ids = 8;

  // Targeted age range.
  // An unset value is equivalent to targeting all ages.
  google.ads.googleads.v16.enums.ReachPlanAgeRangeEnum.ReachPlanAgeRange
      age_range = 2;

  // Targeted genders.
  // An unset value is equivalent to targeting MALE and FEMALE.
  repeated google.ads.googleads.v16.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
  // [ReachPlanService.ListPlannableProducts][google.ads.googleads.v16.services.ReachPlanService.ListPlannableProducts].
  repeated google.ads.googleads.v16.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
  // [ReachPlanService.ListPlannableProducts][google.ads.googleads.v16.services.ReachPlanService.ListPlannableProducts].
  google.ads.googleads.v16.enums.ReachPlanNetworkEnum.ReachPlanNetwork network =
      5;

  // Targeted audiences.
  // If not specified, does not target any specific audience.
  AudienceTargeting audience_targeting = 7;
}

// The duration of a planned campaign.
message CampaignDuration {
  // The duration value in days.
  //
  // This field cannot be combined with the date_range field.
  optional int32 duration_in_days = 2;

  // Date range of the campaign.
  // Dates are in the yyyy-mm-dd format and inclusive.
  // The end date must be < 1 year in the future and the
  // date range must be <= 92 days long.
  //
  // This field cannot be combined with the duration_in_days field.
  google.ads.googleads.v16.common.DateRange date_range = 3;
}

// A product being planned for reach.
message PlannedProduct {
  // Required. Selected product for planning.
  // The code associated with the ad product (for example: Trueview, Bumper).
  // To list the available plannable product codes use
  // [ReachPlanService.ListPlannableProducts][google.ads.googleads.v16.services.ReachPlanService.ListPlannableProducts].
  optional string plannable_product_code = 3
      [(google.api.field_behavior) = REQUIRED];

  // Required. Maximum budget allocation in micros for the selected product.
  // The value is specified in the selected planning currency_code.
  // For example: 1 000 000$ = 1 000 000 000 000 micros.
  optional int64 budget_micros = 4 [(google.api.field_behavior) = REQUIRED];

  // Targeting settings for the selected product.
  // To list the available targeting for each product use
  // [ReachPlanService.ListPlannableProducts][google.ads.googleads.v16.services.ReachPlanService.ListPlannableProducts].
  AdvancedProductTargeting advanced_product_targeting = 5;
}

// 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 or
  // GenerateReachForecastRequest.effective_frequency_limit times that exactly
  // matches the Targeting.
  //
  // Note that a minimum number of unique people must be reached in order for
  // data to be reported. If the minimum number is not met, the on_target_reach
  // value will be rounded to 0.
  optional int64 on_target_reach = 5;

  // Total number of unique people reached at least
  // GenerateReachForecastRequest.min_effective_frequency or
  // GenerateReachForecastRequest.effective_frequency_limit times. This includes
  // people that may fall outside the specified Targeting.
  //
  // Note that a minimum number of unique people must be reached in order for
  // data to be reported. If the minimum number is not met, the total_reach
  // value will be rounded to 0.
  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;

  // A list of effective frequency forecasts. The list is ordered starting with
  // 1+ and ending with the value set in
  // GenerateReachForecastRequest.effective_frequency_limit. If no
  // effective_frequency_limit was set, this list will be empty.
  repeated EffectiveFrequencyBreakdown effective_frequency_breakdowns = 10;

  // Number of unique people reached that exactly matches the Targeting
  // including co-viewers.
  optional int64 on_target_coview_reach = 11;

  // Number of unique people reached including co-viewers. This includes
  // people that may fall outside the specified Targeting.
  optional int64 total_coview_reach = 12;

  // Number of ad impressions that exactly matches the Targeting including
  // co-viewers.
  optional int64 on_target_coview_impressions = 13;

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

  // Number of ad views forecasted for the specified product and targeting.
  // A view is counted when a viewer views a larger portion or the entirety of
  // an ad beyond an impression.
  //
  // See https://support.google.com/google-ads/answer/2375431 for
  // more information on views.
  optional int64 views = 15;
}

// 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.
  //
  // Note that a minimum number of unique people must be reached in order for
  // data to be reported. If the minimum number is not met, the on_target_reach
  // value will be rounded to 0.
  int64 on_target_reach = 1;

  // Number of unique people reached. This includes people that may fall
  // outside the specified Targeting.
  //
  // Note that a minimum number of unique people must be reached in order for
  // data to be reported. If the minimum number is not met, the total_reach
  // value will be rounded to 0.
  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;

  // Number of unique people reached that exactly matches the Targeting
  // including co-viewers.
  optional int64 on_target_coview_reach = 6;

  // Number of unique people reached including co-viewers. This includes
  // people that may fall outside the specified Targeting.
  optional int64 total_coview_reach = 7;

  // Number of ad impressions that exactly matches the Targeting including
  // co-viewers.
  optional int64 on_target_coview_impressions = 8;

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

  // The number of times per selected time unit a user will see an ad, averaged
  // over the number of time units in the forecast length. This field will only
  // be populated for a Target Frequency campaign.
  //
  // See https://support.google.com/google-ads/answer/12400225 for more
  // information about Target Frequency campaigns.
  optional double average_frequency = 10;

  // Number of ad views forecasted for the specified product and targeting.
  // A view is counted when a viewer views a larger portion or the entirety of
  // an ad beyond an impression.
  //
  // See https://support.google.com/google-ads/answer/2375431 for
  // more information on views.
  optional int64 views = 11;
}

// Audience metrics for the planned products.
// These metrics consider the following targeting dimensions:
//
// - Location
// - PlannableAgeRange
// - Gender
// - AudienceTargeting (only for youtube_audience_size)
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;
}

// A breakdown of the number of unique people reached at a given effective
// frequency.
message EffectiveFrequencyBreakdown {
  // The effective frequency [1-10].
  int32 effective_frequency = 1;

  // The number of unique people reached at least effective_frequency times that
  // exactly matches the Targeting.
  //
  // Note that a minimum number of unique people must be reached in order for
  // data to be reported. If the minimum number is not met, the on_target_reach
  // value will be rounded to 0.
  int64 on_target_reach = 2;

  // Total number of unique people reached at least effective_frequency times.
  // This includes people that may fall outside the specified Targeting.
  //
  // Note that a minimum number of unique people must be reached in order for
  // data to be reported. If the minimum number is not met, the total_reach
  // value will be rounded to 0.
  int64 total_reach = 3;

  // The number of users (including co-viewing users) reached for the associated
  // effective_frequency value.
  optional int64 effective_coview_reach = 4;

  // The number of users (including co-viewing users) reached for the associated
  // effective_frequency value within the specified plan demographic.
  optional int64 on_target_effective_coview_reach = 5;
}

// Controls forecast metrics to return.
message ForecastMetricOptions {
  // Indicates whether to include co-view metrics in the response forecast.
  bool include_coview = 1;
}

// Audience targeting for reach forecast.
message AudienceTargeting {
  // List of audiences based on user interests to be targeted.
  repeated google.ads.googleads.v16.common.UserInterestInfo user_interest = 1;
}

// Advanced targeting settings for products.
message AdvancedProductTargeting {
  // Surface targeting settings for this product.
  SurfaceTargeting surface_targeting_settings = 2;

  // Settings for a Target frequency campaign. Must be set when selecting the
  // TARGET_FREQUENCY product.
  //
  // See https://support.google.com/google-ads/answer/12400225 for more
  // information about Target Frequency campaigns.
  TargetFrequencySettings target_frequency_settings = 3;

  // Targeting options for this product.
  oneof advanced_targeting {
    // Settings for YouTube Select targeting.
    YouTubeSelectSettings youtube_select_settings = 1;
  }
}

// Request settings for YouTube Select Lineups
message YouTubeSelectSettings {
  // Lineup for YouTube Select Targeting.
  int64 lineup_id = 1;
}

// A Plannable YouTube Select Lineup for product targeting.
message YouTubeSelectLineUp {
  // The ID of the YouTube Select Lineup.
  int64 lineup_id = 1;

  // The unique name of the YouTube Select Lineup.
  string lineup_name = 2;
}

// The surface targeting combinations available for an ad product.
message SurfaceTargetingCombinations {
  // Default surface targeting applied to the ad product.
  SurfaceTargeting default_targeting = 1;

  // Available surface target combinations for the ad product.
  repeated SurfaceTargeting available_targeting_combinations = 2;
}

// Container for surfaces for a product. Surfaces refer to the available types
// of ad inventories such as In-Feed, In-Stream, and Shorts.
message SurfaceTargeting {
  // List of surfaces available to target.
  repeated google.ads.googleads.v16.enums.ReachPlanSurfaceEnum.ReachPlanSurface
      surfaces = 1;
}

// Target Frequency settings for a supported product.
message TargetFrequencySettings {
  // Required. The time unit used to describe the time frame for
  // target_frequency.
  google.ads.googleads.v16.enums.TargetFrequencyTimeUnitEnum
      .TargetFrequencyTimeUnit time_unit = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The target frequency goal per selected time unit.
  int32 target_frequency = 2 [(google.api.field_behavior) = REQUIRED];
}
