// Copyright 2024 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.cloud.channel.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/channel/v1/common.proto";
import "google/cloud/channel/v1/products.proto";
import "google/protobuf/timestamp.proto";
import "google/type/money.proto";

option go_package = "cloud.google.com/go/channel/apiv1/channelpb;channelpb";
option java_multiple_files = true;
option java_outer_classname = "OffersProto";
option java_package = "com.google.cloud.channel.v1";

// Constraints type for Promotional offers.
enum PromotionalOrderType {
  // Not used.
  PROMOTIONAL_TYPE_UNSPECIFIED = 0;

  // Order used for new customers, trial conversions and upgrades.
  NEW_UPGRADE = 1;

  // All orders for transferring an existing customer.
  TRANSFER = 2;

  // Orders for modifying an existing customer's promotion on the same SKU.
  PROMOTION_SWITCH = 3;
}

// Describes how the reseller will be billed.
enum PaymentPlan {
  // Not used.
  PAYMENT_PLAN_UNSPECIFIED = 0;

  // Commitment.
  COMMITMENT = 1;

  // No commitment.
  FLEXIBLE = 2;

  // Free.
  FREE = 3;

  // Trial.
  TRIAL = 4;

  // Price and ordering not available through API.
  OFFLINE = 5;
}

// Specifies when the payment needs to happen.
enum PaymentType {
  // Not used.
  PAYMENT_TYPE_UNSPECIFIED = 0;

  // Prepay. Amount has to be paid before service is rendered.
  PREPAY = 1;

  // Postpay. Reseller is charged at the end of the Payment cycle.
  POSTPAY = 2;
}

// Represents the type for a monetizable resource(any entity on which billing
// happens). For example, this could be MINUTES for Google Voice and GB for
// Google Drive. One SKU can map to multiple monetizable resources.
enum ResourceType {
  // Not used.
  RESOURCE_TYPE_UNSPECIFIED = 0;

  // Seat.
  SEAT = 1;

  // Monthly active user.
  MAU = 2;

  // GB (used for storage SKUs).
  GB = 3;

  // Active licensed users(for Voice SKUs).
  LICENSED_USER = 4;

  // Voice usage.
  MINUTES = 5;

  // For IaaS SKUs like Google Cloud, monetization is based on usage accrued on
  // your billing account irrespective of the type of monetizable resource. This
  // enum represents an aggregated resource/container for all usage SKUs on a
  // billing account. Currently, only applicable to Google Cloud.
  IAAS_USAGE = 6;

  // For Google Cloud subscriptions like Anthos or SAP.
  SUBSCRIPTION = 7;
}

// Period Type.
enum PeriodType {
  // Not used.
  PERIOD_TYPE_UNSPECIFIED = 0;

  // Day.
  DAY = 1;

  // Month.
  MONTH = 2;

  // Year.
  YEAR = 3;
}

// Represents an offer made to resellers for purchase.
// An offer is associated with a [Sku][google.cloud.channel.v1.Sku], has a plan
// for payment, a price, and defines the constraints for buying.
message Offer {
  option (google.api.resource) = {
    type: "cloudchannel.googleapis.com/Offer"
    pattern: "accounts/{account}/offers/{offer}"
  };

  // Resource Name of the Offer.
  // Format: accounts/{account_id}/offers/{offer_id}
  string name = 1;

  // Marketing information for the Offer.
  MarketingInfo marketing_info = 2;

  // SKU the offer is associated with.
  Sku sku = 3;

  // Describes the payment plan for the Offer.
  Plan plan = 4;

  // Constraints on transacting the Offer.
  Constraints constraints = 5;

  // Price for each monetizable resource type.
  repeated PriceByResource price_by_resources = 6;

  // Start of the Offer validity time.
  google.protobuf.Timestamp start_time = 7;

  // Output only. End of the Offer validity time.
  google.protobuf.Timestamp end_time = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Parameters required to use current Offer to purchase.
  repeated ParameterDefinition parameter_definitions = 9;

  // The deal code of the offer to get a special promotion or discount.
  string deal_code = 12;
}

// Parameter's definition. Specifies what parameter is required to use the
// current Offer to purchase.
message ParameterDefinition {
  // Data type of the parameter.
  enum ParameterType {
    // Not used.
    PARAMETER_TYPE_UNSPECIFIED = 0;

    // Int64 type.
    INT64 = 1;

    // String type.
    STRING = 2;

    // Double type.
    DOUBLE = 3;

    // Boolean type.
    BOOLEAN = 4;
  }

  // Name of the parameter.
  string name = 1;

  // Data type of the parameter. Minimal value, Maximum value and allowed values
  // will use specified data type here.
  ParameterType parameter_type = 2;

  // Minimal value of the parameter, if applicable. Inclusive. For example,
  // minimal commitment when purchasing Anthos is 0.01.
  // Applicable to INT64 and DOUBLE parameter types.
  Value min_value = 3;

  // Maximum value of the parameter, if applicable. Inclusive. For example,
  // maximum seats when purchasing Google Workspace Business Standard.
  // Applicable to INT64 and DOUBLE parameter types.
  Value max_value = 4;

  // If not empty, parameter values must be drawn from this list.
  // For example, [us-west1, us-west2, ...]
  // Applicable to STRING parameter type.
  repeated Value allowed_values = 5;

  // If set to true, parameter is optional to purchase this Offer.
  bool optional = 6;
}

// Represents the constraints for buying the Offer.
message Constraints {
  // Represents constraints required to purchase the Offer for a customer.
  CustomerConstraints customer_constraints = 1;
}

// Represents constraints required to purchase the Offer for a customer.
message CustomerConstraints {
  // Allowed geographical regions of the customer.
  repeated string allowed_regions = 1;

  // Allowed Customer Type.
  repeated CloudIdentityInfo.CustomerType allowed_customer_types = 2;

  // Allowed Promotional Order Type. Present for Promotional offers.
  repeated PromotionalOrderType promotional_order_types = 3;
}

// The payment plan for the Offer. Describes how to make a payment.
message Plan {
  // Describes how a reseller will be billed.
  PaymentPlan payment_plan = 1;

  // Specifies when the payment needs to happen.
  PaymentType payment_type = 2;

  // Describes how frequently the reseller will be billed, such as
  // once per month.
  Period payment_cycle = 3;

  // Present for Offers with a trial period.
  // For trial-only Offers, a paid service needs to start before the trial
  // period ends for continued service.
  // For Regular Offers with a trial period, the regular pricing goes into
  // effect when trial period ends, or if paid service is started before the end
  // of the trial period.
  Period trial_period = 4;

  // Reseller Billing account to charge after an offer transaction.
  // Only present for Google Cloud offers.
  string billing_account = 5;
}

// Represents price by resource type.
message PriceByResource {
  // Resource Type. Example: SEAT
  ResourceType resource_type = 1;

  // Price of the Offer. Present if there are no price phases.
  Price price = 2;

  // Specifies the price by time range.
  repeated PricePhase price_phases = 3;
}

// Represents the price of the Offer.
message Price {
  // Base price.
  google.type.Money base_price = 1;

  // Discount percentage, represented as decimal.
  // For example, a 20% discount will be represent as 0.2.
  double discount = 2;

  // Effective Price after applying the discounts.
  google.type.Money effective_price = 3;

  // Link to external price list, such as link to Google Voice rate card.
  string external_price_uri = 4;
}

// Specifies the price by the duration of months.
// For example, a 20% discount for the first six months, then a 10% discount
// starting on the seventh month.
message PricePhase {
  // Defines the phase period type.
  PeriodType period_type = 1;

  // Defines first period for the phase.
  int32 first_period = 2;

  // Defines first period for the phase.
  int32 last_period = 3;

  // Price of the phase. Present if there are no price tiers.
  Price price = 4;

  // Price by the resource tiers.
  repeated PriceTier price_tiers = 5;
}

// Defines price at resource tier level.
// For example, an offer with following definition :
//
// * Tier 1: Provide 25% discount for all seats between 1 and 25.
// * Tier 2: Provide 10% discount for all seats between 26 and 100.
// * Tier 3: Provide flat 15% discount for all seats above 100.
//
// Each of these tiers is represented as a PriceTier.
message PriceTier {
  // First resource for which the tier price applies.
  int32 first_resource = 1;

  // Last resource for which the tier price applies.
  int32 last_resource = 2;

  // Price of the tier.
  Price price = 3;
}

// Represents period in days/months/years.
message Period {
  // Total duration of Period Type defined.
  int32 duration = 1;

  // Period Type.
  PeriodType period_type = 2;
}
