// Copyright 2025 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.capacityplanner.v1beta;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/capacityplanner/v1beta/location.proto";
import "google/cloud/capacityplanner/v1beta/resource.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.CapacityPlanner.V1Beta";
option go_package = "cloud.google.com/go/capacityplanner/apiv1beta/capacityplannerpb;capacityplannerpb";
option java_multiple_files = true;
option java_outer_classname = "CapacityPlanningServiceProto";
option java_package = "com.google.cloud.capacityplanner.v1beta";
option php_namespace = "Google\\Cloud\\CapacityPlanner\\V1beta";
option ruby_package = "Google::Cloud::CapacityPlanner::V1beta";

// This API allows users to plan for GCP capacity associated with their
// projects. Users can request additional capacity for GCP resources such as
// VMs, PDs, etc.
service CapacityPlanningService {
  option (google.api.default_host) = "capacityplanner.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform,"
      "https://www.googleapis.com/auth/devstorage.full_control";

  // Returns information about the capacity plan.
  rpc GetCapacityPlan(GetCapacityPlanRequest) returns (CapacityPlan) {
    option (google.api.http) = {
      get: "/v1beta/{name=projects/*/capacityPlans/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Returns a list of the capacity plans that are in the parent parameter and
  // match your specified filters.
  // (The maximum list length is limited by the pageSize parameter.)
  rpc QueryCapacityPlans(QueryCapacityPlansRequest)
      returns (QueryCapacityPlansResponse) {
    option (google.api.http) = {
      get: "/v1beta/{parent=organizations/*}/capacityPlans:query"
      additional_bindings {
        get: "/v1beta/{parent=folders/*}/capacityPlans:query"
      }
      additional_bindings {
        get: "/v1beta/{parent=projects/*}/capacityPlans:query"
      }
    };
    option (google.api.method_signature) = "parent";
  }

  // Query capacity plan insights that are in the parent parameter and match
  // your specified filters.
  rpc QueryCapacityPlanInsights(QueryCapacityPlanInsightsRequest)
      returns (QueryCapacityPlanInsightsResponse) {
    option (google.api.http) = {
      post: "/v1beta/{parent=projects/*}/capacityPlanInsights:query"
      body: "*"
    };
    option (google.api.method_signature) = "parent,capacity_plan_filters";
  }
}

// The state of a capacity demand.
enum State {
  // The state is unspecified.
  STATE_UNSPECIFIED = 0;

  // The demand is pending review.
  PENDING_REVIEW = 1;

  // The demand is in review.
  IN_REVIEW = 3;

  // The demand is provisionally approved.
  APPROVED_PROVISIONAL = 8;

  // The demand is obsolete.
  OBSOLETE = 5;

  // The demand cannot be fulfilled.
  CANNOT_BE_FULFILLED = 7;

  // The demand is on hold, contact sales.
  ON_HOLD_CONTACT_SALES = 9;

  // The demand is in fulfillment.
  IN_FULFILLMENT = 10;
}

// CapacityType is the type of the capacity plan.
enum CapacityType {
  // Default value.
  CAPACITY_TYPE_UNKNOWN = 0;

  // Latest inorganic data stored in horizon DB that is in draft state.
  CAPACITY_TYPE_INORGANIC_DRAFT = 1;

  // Latest inorganic data stored in horizon DB that are pending i.e. submitted
  // or assessment.
  CAPACITY_TYPE_INORGANIC_PENDING = 2;

  // Latest inorganic data stored in horizon DB that has been approved.
  CAPACITY_TYPE_INORGANIC_APPROVED = 3;
}

// Request for getting a capacity plan.
message GetCapacityPlanRequest {
  // Required. The name of the capacity plan to retrieve.
  // Format: projects/{project}/capacityPlans/{capacity_plan}
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "capacityplanner.googleapis.com/CapacityPlan"
    }
  ];
}

// Request for querying capacity plans.
message QueryCapacityPlansRequest {
  // Required. The parent resource container.
  // Format:
  //         projects/{project} or
  //         folders/{folder} or
  //         organizations/{organization}
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "capacityplanner.googleapis.com/CapacityPlan"
    }
  ];

  // Optional. The maximum number of plans to return per page. The service may
  // return fewer than this value. If unspecified, the server will use a
  // sensible default. The maximum value is 1000; values above 1000 will be
  // coerced to 1000.
  int32 page_size = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A page token, received from a previous `QueryCapacityPlans` call.
  // Provide this to retrieve the subsequent page.
  string page_token = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The Google Cloud Platform location of capacity plans. If
  // unspecified, all locations will be included.
  string location = 4 [(google.api.field_behavior) = OPTIONAL];
}

// Response of querying capacity plans.
message QueryCapacityPlansResponse {
  // List of capacity plans.
  repeated CapacityPlan capacity_plans = 1;

  // Token to retrieve the next page of results. This will be empty if there are
  // no more pages.
  string next_page_token = 2;
}

// Request for capacity plan insights.
message QueryCapacityPlanInsightsRequest {
  // Required. The parent resource container.
  // Format: projects/{project}
  string parent = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The filters to apply to the capacity plan.
  CapacityPlanFilters capacity_plan_filters = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Response for capacity plan insights.
message QueryCapacityPlanInsightsResponse {
  // Optional. The aggregated capacity plan view. This is the aggregated view of
  // all the capacity plans that match the filters.
  CapacityPlanView aggregated_capacity_plan_view = 1
      [(google.api.field_behavior) = OPTIONAL];
}

// CapacityPlanFilters is a set of filters to apply to the capacity plan.
message CapacityPlanFilters {
  // Required. The capacity plan keys to include in the response.
  repeated CapacityPlanKey keys = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The capacity types to include in the response.
  repeated CapacityType capacity_types = 2
      [(google.api.field_behavior) = REQUIRED];

  // Optional. Optional capacity plan id. Should be populated for request page
  // to lock based on the same capacity plan.
  string capacity_plan_id = 3 [(google.api.field_behavior) = OPTIONAL];
}

// CapacityPlanKey is a the unique identifier for each Capacity Plan.
message CapacityPlanKey {
  // Required. The resource container associated with the capacity plan.
  ResourceContainer resource_container = 1
      [(google.api.field_behavior) = REQUIRED];

  // Required. The resource id key associated with the capacity plan.
  ResourceIdKey resource_id_key = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Identifier of location.
  LocationIdentifier location_id = 3 [(google.api.field_behavior) = REQUIRED];
}

// CapacityPlanView contains the capacity plan key and the time series views.
message CapacityPlanView {
  // Required. The capacity plan key associated with the capacity plan view.
  CapacityPlanKey key = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The time series views associated with the capacity plan view.
  repeated TimeSeriesView time_series_views = 2
      [(google.api.field_behavior) = REQUIRED];
}

// TimeSeriesView contains capacity_value which has the timeseries for a given
// type. Each type as a single timeseries associated with it.
message TimeSeriesView {
  // Required. The capacity type associated with the time series view.
  CapacityType type = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The capacity value associated with the time series view.
  DemandValue capacity_value = 2 [(google.api.field_behavior) = REQUIRED];
}

// A plan for additional capacity needed by a Google Cloud Platform project.
// This is synonymous with CapacityDemand, CapacityRequest, and
// CapacityDemandRequest.
message CapacityPlan {
  option (google.api.resource) = {
    type: "capacityplanner.googleapis.com/CapacityPlan"
    pattern: "projects/{project}/capacityPlans/{capacity_plan}"
    plural: "capacityPlans"
    singular: "capacityPlan"
  };

  // Identifier. The  name of the capacity plan.
  //
  // Format:
  //         projects/{project}/capacityPlans/{capacity_plan_id}
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Optional. The metadata associated with a capacity demand.
  DemandMetadata capacity_demand_metadata = 2
      [(google.api.field_behavior) = OPTIONAL];

  // Required. The capacity demand associated with a service.
  repeated ServiceDemand service_demands = 3
      [(google.api.field_behavior) = REQUIRED];

  // Output only. User who created the capacity plan.
  User reporter = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. State of the plan.
  State state = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Timestamp when the plan was created.
  google.protobuf.Timestamp create_time = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Timestamp when the plan was last updated.
  google.protobuf.Timestamp update_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Optional. Description of the plan.
  string description = 8 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Title of the plan.
  string title = 9 [(google.api.field_behavior) = OPTIONAL];
}

// The metadata associated with a capacity demand.
message DemandMetadata {
  // Optional. The preferences associated with a capacity demand.
  repeated DemandPreference demand_preferences = 1
      [(google.api.field_behavior) = OPTIONAL];
}

// Preference associated with a request, such as flexibility with alternate
// resource type.
message DemandPreference {
  // Output only. The preference id.
  string preference_id = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The value of demand preference.
  Value value = 2 [(google.api.field_behavior) = REQUIRED];
}

// Capacity demand for a service.
message ServiceDemand {
  // Required. Name of the service.
  string service = 1 [(google.api.field_behavior) = REQUIRED];

  // Optional. The metadata associated with a service demand.
  DemandMetadata demand_metadata = 2 [(google.api.field_behavior) = OPTIONAL];

  // Required. The demand associated with the resources.
  repeated ResourceDemand resource_demands = 3
      [(google.api.field_behavior) = REQUIRED];
}

// Capacity demand for a resource.
message ResourceDemand {
  // Output only. Identifier of resource demand.
  string id = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The resource container associated with the demand.
  ResourceContainer resource_container = 2
      [(google.api.field_behavior) = REQUIRED];

  // Required. Identifier of resource.
  ResourceIdentifier resource_id = 3 [(google.api.field_behavior) = REQUIRED];

  // Required. Identifier of location.
  LocationIdentifier location_id = 4 [(google.api.field_behavior) = REQUIRED];

  // Output only. State of the resource demand.
  State state = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. User who reported the demand.
  User reporter = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Timestamp when the demand was created.
  google.protobuf.Timestamp create_time = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Timestamp when the demand was last updated.
  google.protobuf.Timestamp update_time = 8
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The demand values associated with the resource.
  DemandValues demand_values = 9 [(google.api.field_behavior) = REQUIRED];

  // Optional. The metadata associated with the demand.
  DemandMetadata demand_metadata = 10 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The child resource demands associated with the resource.
  repeated ChildResourceDemand child_resource_demands = 11
      [(google.api.field_behavior) = OPTIONAL];
}

// A user who created or updated a capacity demand.
message User {
  // Required. Email of the user.
  string email = 1 [(google.api.field_behavior) = REQUIRED];
}

// The capacity demand values for a resource.
message DemandValues {
  // Required. The demand values.
  repeated DemandValue values = 1 [(google.api.field_behavior) = REQUIRED];
}

// Capacity demand value for a single resource attribute such as CPU count,
// vertex AI peak QPM, etc.
message DemandValue {
  // Required. The name of the demand value such as CPU count.
  string name = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The demand values at different time points.
  repeated TimeValue time_values = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Unit of measurement.
  Unit unit = 3 [(google.api.field_behavior) = REQUIRED];
}

// Capacity demand value for a single time point.
message TimeValue {
  // Required. The time point. If this demand value is non-temporal, set time to
  // -1.
  google.protobuf.Timestamp time = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The demand value at the time point.
  optional double value = 2 [(google.api.field_behavior) = REQUIRED];
}

// Capacity demand for a child resource such as shapes.
message ChildResourceDemand {
  // Required. Identifier of resource.
  ResourceIdentifier resource_id = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The demand values associated with the child resource.
  DemandValues demand_values = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The metadata associated with the child resource demand.
  DemandMetadata demand_metadata = 3 [(google.api.field_behavior) = OPTIONAL];
}
