syntax = "proto3";

package tidb_cloud_open_api.nextgen.v1beta2;

import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/timestamp.proto";
// buf:lint:ignore IMPORT_USED
import "google/rpc/status.proto"; // This is used by `responses.value.schema.json_schema.ref` in the swagger definition.
import "protoc-gen-openapiv2/options/annotations.proto";
import "tidb_cloud_open_api/common/v1beta1/region.proto";
import "tidb_cloud_open_api/common/v1beta1/service_plan.proto";

option go_package = "tidb_cloud_open_api/nextgen/v1beta2";
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
  swagger: "2.0"
  host: "cloud.tidbapi.com"
  base_path: "/v1beta2"
  info: {
    version: "v1beta2"
    title: "TiDB Cloud Premium API"
    description: "TiDB Cloud Premium API"
  }
  schemes: HTTPS
  consumes: "application/json"
  produces: "application/json"

  responses: {
    key: "400"
    value: {
      description: "A request field is invalid."
      schema: {
        json_schema: {ref: ".google.rpc.Status"}
      }
    }
  }
  responses: {
    key: "401"
    value: {
      description: "The API key cannot be authenticated."
      schema: {
        json_schema: {ref: ".google.rpc.Status"}
      }
    }
  }
  responses: {
    key: "403"
    value: {
      description: "The API key does not have permission to access the resource."
      schema: {
        json_schema: {ref: ".google.rpc.Status"}
      }
    }
  }
  responses: {
    key: "429"
    value: {
      description: "You have exceeded the rate limit."
      schema: {
        json_schema: {ref: ".google.rpc.Status"}
      }
    }
  }
  responses: {
    key: "500"
    value: {
      description: "Internal server error."
      schema: {
        json_schema: {ref: ".google.rpc.Status"}
      }
    }
  }
};

// (-- api-linter: core::0121::resource-must-support-get=disabled
//     aip.dev/not-precedent: We need to do this because reasons. --)
service RegionService {
  // List all regions.
  rpc ListRegions(ListRegionsRequest) returns (ListRegionsResponse) {
    option (google.api.http) = {get: "/regions"};
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "List regions"
      tags: "public"
      tags: "Region"
      description: "Lists the regions where you can create a TiDB Cloud Premium instance. You can filter results by cloud provider or service plan."
      extensions: {
        key: "x-code-samples"
        value: {
          list_value: {
            values: {
              struct_value: {
                fields: {
                  key: "lang"
                  value: {string_value: "curl"}
                }
                fields: {
                  key: "label"
                  value: {string_value: "curl"}
                }
                fields: {
                  key: "source"
                  value: {string_value: "curl --location 'https://cloud.tidbapi.com/v1beta2/regions' \\\n--digest --user 'YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY' \\\n--header 'Accept: application/json'"}
                }
              }
            }
          }
        }
      }
    };
  }

  rpc ListCloudProviders(ListCloudProvidersRequest) returns (ListCloudProvidersResponse) {
    option (google.api.http) = {get: "/regions:listCloudProviders"};
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "List cloud providers"
      description: "Lists all available cloud providers for a given service plan."
    };
  }

  rpc ListOpsAuditLogSettings(ListOpsAuditLogSettingsRequest) returns (ListOpsAuditLogSettingsResponse) {
    option (google.api.http) = {get: "/opsAuditLogSettings"};
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "List ops audit log settings"
      description: "Lists the operational audit log settings for all regions. You can filter results by cloud provider, service plan, or region."
    };
  }

  // only used for BYOC
  rpc ListRegionCapacities(ListRegionCapacitiesRequest) returns (ListRegionCapacitiesResponse) {
    option (google.api.http) = {get: "/regions:listCapacities"};
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "List region capacities"
      description: "Lists the resource capacities for all regions. Currently only supports BYOC service plan."
    };
  }

  rpc ListByocVcpuPools(ListByocVcpuPoolsRequest) returns (ListByocVcpuPoolsResponse) {
    option (google.api.http) = {get: "/byocVcpuPools"};
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "List BYOC vCPU pools"
      description: "Lists the BYOC resource pool inventory grouped by cloud provider and region for the current organization."
    };
  }

  rpc UpdateByocVcpuPool(UpdateByocVcpuPoolRequest) returns (ByocVcpuPool) {
    option (google.api.http) = {
      patch: "/byocVcpuPools/{resource_pool_id}"
      body: "byoc_vcpu_pool"
    };
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "Update BYOC vCPU pool limit"
      description: "Updates the vCPU limit of a BYOC resource pool for the current organization."
    };
  }

  rpc GetByocSharedComponentScaleConstraints(GetByocSharedComponentScaleConstraintsRequest) returns (ByocSharedComponentScaleConstraints) {
    option (google.api.http) = {get: "/byocVcpuPools/{resource_pool_id}/sharedComponentScaleConstraints"};
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "Get BYOC shared component scale constraints"
      description: "Returns the current shared component scale constraints and usage preview for a BYOC resource pool in the current organization."
    };
  }

  rpc ScaleByocSharedComponents(ScaleByocSharedComponentsRequest) returns (ScaleByocSharedComponentsResponse) {
    option (google.api.http) = {
      post: "/byocVcpuPools/{resource_pool_id}:scaleByocSharedComponents"
      body: "*"
    };
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "Scale BYOC shared components"
      description: "Validates or submits a BYOC shared component scale plan for a BYOC resource pool in the current organization."
    };
  }

  rpc ListNodeSpecs(ListNodeSpecsRequest) returns (ListNodeSpecsResponse) {
    option (google.api.http) = {get: "/regions/{region_id}/nodeSpecs"};
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "List node specifications"
      tags: "Region"
      description: "Lists the TiKV or TiFlash node specifications available when creating a BYOC resource pool in a region."
      extensions: {
        key: "x-code-samples"
        value: {
          list_value: {
            values: {
              struct_value: {
                fields: {
                  key: "lang"
                  value: {string_value: "curl"}
                }
                fields: {
                  key: "label"
                  value: {string_value: "curl"}
                }
                fields: {
                  key: "source"
                  value: {string_value: "curl --location 'https://cloud.tidbapi.com/v1beta2/regions/aws-us-west-2/nodeSpecs?organizationId=73127&componentType=NODE_SPEC_COMPONENT_TYPE_TIKV&pageSize=20' \\\n--digest --user 'YOUR_PUBLIC_KEY:YOUR_PRIVATE_KEY' \\\n--header 'Accept: application/json'"}
                }
              }
            }
          }
        }
      }
    };
  }

  rpc PlanResourcePoolCidr(PlanResourcePoolCidrRequest) returns (PlanResourcePoolCidrResponse) {
    option (google.api.http) = {get: "/regions/{region_id}:planResourcePoolCidr"};
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "Plan a resource pool CIDR"
      tags: "Region"
      description: "Returns current CIDR restrictions, excluded CIDRs, and a recommendation for the authenticated organization and selected region."
    };
  }

  rpc ValidateResourcePoolCidr(ValidateResourcePoolCidrRequest) returns (ValidateResourcePoolCidrResponse) {
    option (google.api.http) = {
      post: "/regions/{region_id}:validateResourcePoolCidr"
      body: "*"
    };
    option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
      summary: "Validate a resource pool CIDR"
      tags: "Region"
      description: "Validates a customer-supplied CIDR and returns its aggregate dataplane node capacity and blocking findings."
    };
  }
}

message ListRegionsRequest {
  // The cloud provider. If specified, only regions belonging to the specified cloud provider are returned.
  string cloud_provider = 1 [(google.api.field_behavior) = OPTIONAL];

  // The plan of the service. If specified, only regions that support the specified service plan are returned.
  common.v1beta1.ServicePlan service_plan = 2 [(google.api.field_behavior) = OPTIONAL];

  // The maximum number of regions to return. If not specified, at most 10 regions will be returned. The maximum value is `100`. Values greater than `100` are set to `100`.
  int32 page_size = 100 [
    (google.api.field_behavior) = OPTIONAL,
    (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
      example: "10"
      default: "10"
      minimum: 1
      maximum: 100
    }
  ];

  // The pagination token received from a previous [List regions](#tag/Region/operation/RegionService_ListRegions) request. Use this token to retrieve the next page of results.
  //
  // **Note**: When paginating, all other parameters must match the original request.
  string page_token = 101 [(google.api.field_behavior) = OPTIONAL];

  // The number of regions to skip before returning results. If the value exceeds the total number of regions, the response is `200` with an empty list and no `nextPageToken`.
  int32 skip = 102 [(.google.api.field_behavior) = OPTIONAL];
}

message ListRegionsResponse {
  // A list of regions that match the query.
  repeated common.v1beta1.Region regions = 1;

  // The total number of regions that match the query.
  int32 total_size = 100;

  // The token to retrieve the next page of results. Use this value as the `pageToken` parameter in the next request. This field is empty when there are no more pages.
  string next_page_token = 101;
}

message ListCloudProvidersRequest {
  // If specified, only cloud providers of the specified region will be returned.
  common.v1beta1.ServicePlan service_plan = 1 [(google.api.field_behavior) = OPTIONAL];

  // The maximum number of cloud providers to return. The service may return fewer than this value.
  // If unspecified, at most X cloud providers will be returned.
  // The maximum value is X; values above X will be coerced to X.
  int32 page_size = 100 [(google.api.field_behavior) = OPTIONAL];

  // A page token, received from a previous `ListCloudProviders` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to `ListCloudProviders` must match
  // the call that provided the page token.
  string page_token = 101 [(google.api.field_behavior) = OPTIONAL];
}

message ListCloudProvidersResponse {
  // The list of cloud providers.
  repeated common.v1beta1.Region.CloudProvider cloud_providers = 1;

  // The list of cloud providers with supported service plans and display names.
  repeated CloudProviderPlan cloud_provider_plans = 2;

  // The total number of cloud providers that match the query.
  int32 total_size = 100;

  // A token, which can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 101;

  message CloudProviderPlan {
    common.v1beta1.Region.CloudProvider cloud_provider = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
    repeated common.v1beta1.ServicePlan service_plans = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
    repeated common.v1beta1.ServicePlanInfo supported_service_plans = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  }
}

message ListOpsAuditLogSettingsRequest {
  // If specified, only regions of the specified cloud provider will be returned.
  string cloud_provider = 1 [(google.api.field_behavior) = OPTIONAL];

  // If specified, only regions that support the specified service plan will be returned.
  common.v1beta1.ServicePlan service_plan = 2 [(google.api.field_behavior) = OPTIONAL];

  // If specified, only the region with the specified region ID will be returned.
  string region_id = 3 [(google.api.field_behavior) = OPTIONAL];

  // If specified, only regions with ops audit log enabled or disabled will be returned.
  repeated bool status = 4 [(google.api.field_behavior) = OPTIONAL];

  // The maximum number of regions to return. The service may return fewer than this value.
  // If unspecified, at most X regions will be returned.
  // The maximum value is X; values above X will be coerced to X.
  int32 page_size = 100 [(google.api.field_behavior) = OPTIONAL];

  // A page token, received from a previous `ListRegions` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to `ListRegions` must match
  // the call that provided the page token.
  string page_token = 101 [(google.api.field_behavior) = OPTIONAL];

  // The number of individual resources to skip before starting to return results.
  // If the skip value causes the cursor to move past the end of the collection,
  // the response will be 200 OK with an empty result set and no next_page_token.
  int32 skip = 102 [(.google.api.field_behavior) = OPTIONAL];
}

message ListOpsAuditLogSettingsResponse {
  // The list of ops audit log settings.
  repeated OpsAuditLogSetting ops_audit_log_settings = 1;

  // The total number of regions that match the query.
  int32 total_size = 100;

  // A token, which can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 101;
}

message OpsAuditLogSetting {
  common.v1beta1.Region region = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  bool enabled = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  LogLocation log_location = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  LogRotation log_rotation = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  message LogLocation {
    string bucket_uri = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
    string role_arn = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
    string account_id = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
    string external_id = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  message LogRotation {
    int64 file_size_limit_mb = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
    int64 rotation_interval_min = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }
}

message ListRegionCapacitiesRequest {
  // If specified, only regions of the specified cloud provider will be returned.
  string cloud_provider = 1 [(google.api.field_behavior) = OPTIONAL];

  // Only BYOC is supported for now.
  common.v1beta1.ServicePlan service_plan = 2 [(google.api.field_behavior) = REQUIRED];

  // If specified, will return the usage between the time range.
  UsageRequest usage = 3 [(google.api.field_behavior) = OPTIONAL];

  // The maximum number of regions to return. The service may return fewer than this value.
  // If unspecified, at most X regions will be returned.
  // The maximum value is X; values above X will be coerced to X.
  int32 page_size = 100 [(google.api.field_behavior) = OPTIONAL];

  // A page token, received from a previous `ListRegions` call.
  // Provide this to retrieve the subsequent page.
  //
  // When paginating, all other parameters provided to `ListRegions` must match
  // the call that provided the page token.
  string page_token = 101 [(google.api.field_behavior) = OPTIONAL];

  // The number of individual resources to skip before starting to return results.
  // If the skip value causes the cursor to move past the end of the collection,
  // the response will be 200 OK with an empty result set and no next_page_token.
  int32 skip = 102 [(.google.api.field_behavior) = OPTIONAL];

  message UsageRequest {
    google.protobuf.Timestamp start_time = 1 [(google.api.field_behavior) = REQUIRED];
    google.protobuf.Timestamp end_time = 2 [(google.api.field_behavior) = REQUIRED];
  }
}

message ListRegionCapacitiesResponse {
  // The list of ops audit log settings.
  repeated RegionCapacity capacities = 1;

  // The total number of regions that match the query.
  int32 total_size = 100;

  // A token, which can be sent as `page_token` to retrieve the next page.
  // If this field is omitted, there are no subsequent pages.
  string next_page_token = 101;

  message RegionCapacity {
    common.v1beta1.Region region = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
    int64 total_vcpus_limit = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
    int64 used_vcpus = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

    repeated UsageMetrics history_usages = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  message UsageMetrics {
    google.protobuf.Timestamp metrics_time = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
    int64 used_vcpus = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }
}

// (-- api-linter: core::0158::request-page-size-field=disabled
//     aip.dev/not-precedent: this is a page-style read model that always returns the full grouped inventory. --)
// (-- api-linter: core::0158::request-page-token-field=disabled
//     aip.dev/not-precedent: this is a page-style read model that always returns the full grouped inventory. --)
message ListByocVcpuPoolsRequest {
  // If specified, only pools of the specified cloud provider will be returned.
  string cloud_provider = 1 [(google.api.field_behavior) = OPTIONAL];

  // If specified, only pools of the specified region will be returned.
  // Format: {cloud_provider}-{region_code}. For example, aws-us-west-2.
  string region_id = 2 [(google.api.field_behavior) = OPTIONAL];
}

message UpdateByocVcpuPoolRequest {
  string resource_pool_id = 1 [(google.api.field_behavior) = REQUIRED];
  ByocVcpuPool byoc_vcpu_pool = 2 [(google.api.field_behavior) = REQUIRED];
}

message GetByocSharedComponentScaleConstraintsRequest {
  string resource_pool_id = 1 [(google.api.field_behavior) = REQUIRED];
}

message ScaleByocSharedComponentsRequest {
  // Scales existing shared components under the selected BYOC resource pool.
  // This API does not create a brand-new shared component when the shared pool
  // does not already contain the corresponding component.
  string resource_pool_id = 1 [(google.api.field_behavior) = REQUIRED];
  optional ByocSharedComponentScaleTarget tikv = 2 [(google.api.field_behavior) = OPTIONAL];
  // Requests may also update the component spec or storage while node_count
  // remains 0, as long as the shared pool already contains a TiFlash Write
  // component whose current node_count is 0.
  optional ByocSharedComponentScaleTarget tiflash_write = 3 [(google.api.field_behavior) = OPTIONAL];
  // Requests may also update the component spec or storage while node_count
  // remains 0, as long as the shared pool already contains a TiFlash Compute
  // component whose current node_count is 0.
  optional ByocSharedComponentScaleTarget tiflash_compute = 4 [(google.api.field_behavior) = OPTIONAL];
  bool validate_only = 100 [(google.api.field_behavior) = OPTIONAL];
}

// (-- api-linter: core::0123::resource-annotation=disabled
//     aip.dev/not-precedent: This is a page-specific read/write model rather than a standalone resource. --)
message ByocVcpuPool {
  // The BYOC resource pool ID as a plain string id.
  string resource_pool_id = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  string name = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  // The control-plane recorded dataplane locator used by clients for O11Y discovery.
  // Its presence does not guarantee runtime discovery or metrics query success.
  string dataplane_id = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  optional int64 vcpus_limit = 4 [(google.api.field_behavior) = OPTIONAL];
  int64 vcpus_used = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Whether this pool is the default BYOC pool for the current organization
  // under the same cloud provider and region.
  bool is_default = 6 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Availability scope of the underlying resource pool.
  HighAvailabilityType high_availability_type = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Runtime placement zones reported by dataplane-manager for the resource pool.
  ZoneConfig zone_config = 8 [(google.api.field_behavior) = OUTPUT_ONLY];
  State state = 9 [(google.api.field_behavior) = OUTPUT_ONLY];
  TidbInstancesState tidb_instances_state = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  enum State {
    STATE_UNSPECIFIED = 0;
    AVAILABLE = 1;
    MODIFYING = 2;
  }

  enum HighAvailabilityType {
    HIGH_AVAILABILITY_TYPE_UNSPECIFIED = 0;
    REGIONAL = 1;
    ZONAL = 2;
  }

  message ZoneConfig {
    // Explicit node zones used by the dataplane nodes.
    repeated string node_zones = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  message TidbInstancesState {
    int32 active = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
    int32 modifying = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
    int32 creating = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
    int32 deleting = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  }
}

message ByocSharedComponentScaleConstraints {
  string resource_pool_id = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 vcpus_limit = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  ByocSharedComponentScalePreviewSummary preview = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  repeated ByocSharedComponentScaleConstraint components = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ScaleByocSharedComponentsResponse {
  ByocSharedComponentScalePreviewSummary preview = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  repeated ByocSharedComponentScalePlanComponent components = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  string operation_id = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ListNodeSpecsRequest {
  string region_id = 1 [(google.api.field_behavior) = REQUIRED];
  string organization_id = 2 [(google.api.field_behavior) = REQUIRED];
  NodeSpecComponentType component_type = 3 [(google.api.field_behavior) = REQUIRED];
  int32 page_size = 100 [(google.api.field_behavior) = OPTIONAL];
  string page_token = 101 [(google.api.field_behavior) = OPTIONAL];
}

message ListNodeSpecsResponse {
  repeated NodeSpec node_specs = 1;
  NodeCountOptions node_count_options = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  int32 total_size = 100;
  string next_page_token = 101;
}

message PlanResourcePoolCidrRequest {
  // The logical region in which the resource pool will be created.
  string region_id = 1 [(google.api.field_behavior) = REQUIRED];
  // The intended availability scope. If unspecified, the default is REGIONAL.
  ByocVcpuPool.HighAvailabilityType high_availability_type = 2 [(google.api.field_behavior) = OPTIONAL];
}

message PlanResourcePoolCidrResponse {
  // The selected logical region.
  string region_id = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  // The cloud provider of the selected region.
  common.v1beta1.Region.CloudProvider cloud_provider = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  // The effective CIDR policy for the selected provider and region.
  ResourcePoolCidrPolicy policy = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  // CIDRs excluded from recommendation and create.
  repeated ResourcePoolCidrExclusion exclusions = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  // The result of the recommendation search.
  RecommendationStatus recommendation_status = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
  // The recommended CIDR and its derived node capacity. Present only when recommendation_status is AVAILABLE.
  optional ResourcePoolCidrRecommendation recommendation = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  // (-- api-linter: core::0216::synonyms=disabled
  //     aip.dev/not-precedent: This describes the outcome of a recommendation search, not resource lifecycle state. --)
  enum RecommendationStatus {
    RECOMMENDATION_STATUS_UNSPECIFIED = 0;
    AVAILABLE = 1;
    EXHAUSTED = 2;
  }
}

message ValidateResourcePoolCidrRequest {
  // The logical region in which the resource pool will be created.
  string region_id = 1 [(google.api.field_behavior) = REQUIRED];
  // The CIDR to validate.
  string cidr = 2 [(google.api.field_behavior) = REQUIRED];
  // The intended availability scope. If unspecified, the default is REGIONAL.
  ByocVcpuPool.HighAvailabilityType high_availability_type = 3 [(google.api.field_behavior) = OPTIONAL];
}

message ValidateResourcePoolCidrResponse {
  // The selected logical region.
  string region_id = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  // The cloud provider of the selected region.
  common.v1beta1.Region.CloudProvider cloud_provider = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  // The trimmed submitted value. A valid value is canonical.
  string cidr = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  // The maximum aggregate steady-state dataplane node count supported across the resource pool and its TiDB instances.
  // Present only when CSNG reports supported=true; independent overlap findings may still be present.
  optional int64 supported_node_count = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  // All known findings that block resource-pool creation.
  repeated ResourcePoolCidrValidationFinding blocking_findings = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ResourcePoolCidrPolicy {
  // Private IPv4 ranges accepted by common validation.
  repeated string supported_private_cidrs = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Inclusive provider-specific prefix guidance. An empty list advertises no additional client-side restriction.
  repeated ResourcePoolCidrPrefixRange allowed_prefix_ranges = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ResourcePoolCidrPrefixRange {
  int32 min_prefix_length = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  int32 max_prefix_length = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ResourcePoolCidrRecommendation {
  // The recommended canonical CIDR.
  string cidr = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  // The maximum aggregate steady-state dataplane node count supported across the resource pool and its TiDB instances.
  int64 supported_node_count = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ResourcePoolCidrExclusion {
  Type type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  string cidr = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Present only for RESOURCE_POOL.
  optional string resource_pool_id = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Present only for RESOURCE_POOL.
  optional string resource_pool_display_name = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Present only for RESOURCE_POOL.
  optional string region_id = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Present only for RESOURCE_POOL.
  optional common.v1beta1.Region.CloudProvider cloud_provider = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

  enum Type {
    TYPE_UNSPECIFIED = 0;
    RESOURCE_POOL = 1;
    O11Y_CLUSTER = 2;
    TIDB_CLOUD_RESERVED = 3;
  }
}

message ResourcePoolCidrValidationFinding {
  Code code = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Human-readable fallback text. Clients use code for behavior and localization.
  string message = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Present only for an overlap finding.
  optional ResourcePoolCidrExclusion conflicting_exclusion = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  enum Code {
    CODE_UNSPECIFIED = 0;
    INVALID_CIDR = 1;
    CIDR_NOT_PRIVATE = 2;
    CIDR_PREFIX_UNSUPPORTED = 3;
    CIDR_OVERLAPS_RESOURCE_POOL = 4;
    CIDR_OVERLAPS_O11Y = 5;
    CIDR_OVERLAPS_RESERVED_NETWORK = 6;
  }
}

message ResourcePoolCidrValidationError {
  repeated ResourcePoolCidrValidationFinding blocking_findings = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message NodeSpec {
  string node_spec_key = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  string display_name = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  NodeSpecComponentType component_type = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 cpu = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 memory_gi = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
  bool is_default = 6 [(google.api.field_behavior) = OUTPUT_ONLY];
  // Customer-configurable data storage. Service-managed storage is not returned.
  repeated NodeSpecStorage storages = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// (-- api-linter: core::0123::resource-annotation=disabled
//     aip.dev/not-precedent: `name` identifies embedded storage, not a standalone resource. --)
message NodeSpecStorage {
  // The storage name. Only `data` is returned.
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 default_size_gi = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 min_size_gi = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 max_size_gi = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  optional bool resizable = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
  optional int64 current_size_gi = 6 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message NodeCountOptions {
  int64 default_node_count = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 min_node_count = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 max_node_count = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  NodeCountRule rule = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message NodeCountRule {
  NodeCountRuleType type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 value = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ByocSharedComponentScalePreviewSummary {
  int64 current_vcpus_used = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 scaling_vcpus_used = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 max_vcpus_limit = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  bool allowed = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  repeated string blocking_reasons = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ByocSharedComponentScaleConstraint {
  ByocSharedComponentType component_type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  string component_id = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  bool exists = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  string phase = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  ByocSharedComponentScaleTarget current = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
  repeated ByocSharedComponentScaleConstraintReason blocking_reasons = 6 [(google.api.field_behavior) = OUTPUT_ONLY];
  ByocSharedComponentScaleNodeCountConstraints node_count_constraints = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
  ByocSharedComponentScaleNodeSpecConstraints node_spec_constraints = 8 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ByocSharedComponentScalePlanComponent {
  ByocSharedComponentType component_type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  string component_id = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  ByocSharedComponentScaleTarget current = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  ByocSharedComponentScaleTarget target = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  bool allowed = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
  repeated string blocking_reasons = 6 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ByocSharedComponentScaleTarget {
  optional int64 node_count = 1 [(google.api.field_behavior) = OPTIONAL];
  optional int64 cpu = 2 [(google.api.field_behavior) = OPTIONAL];
  optional int64 memory_gi = 3 [(google.api.field_behavior) = OPTIONAL];
  repeated ByocSharedComponentStorage storages = 4 [(google.api.field_behavior) = OPTIONAL];
}

message ByocSharedComponentStorage {
  string storage_name = 1 [(google.api.field_behavior) = REQUIRED];
  optional int64 size_gi = 2 [(google.api.field_behavior) = OPTIONAL];
}

message ByocSharedComponentScaleConstraintReason {
  string code = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  string message = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ByocSharedComponentScaleNodeCountConstraints {
  int64 current = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 min = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 max = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  ByocSharedComponentScaleNodeCountRule rule = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  bool allow_cross_zero = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ByocSharedComponentScaleNodeCountRule {
  string type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 value = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ByocSharedComponentScaleNodeSpecConstraints {
  string current = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  repeated ByocSharedComponentScaleNodeSpecCandidate candidates = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// (-- api-linter: core::0123::resource-annotation=disabled
//     aip.dev/not-precedent: `name` here is a display label for a node spec candidate, not a resource name. --)
message ByocSharedComponentScaleNodeSpecCandidate {
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 cpu = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 memory_gi = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  bool available = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  bool is_current = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
  repeated ByocSharedComponentScaleConstraintReason reasons = 6 [(google.api.field_behavior) = OUTPUT_ONLY];
  ByocSharedComponentScaleRequiredMinSpec required_min_spec = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
  repeated ByocSharedComponentScaleStorageConstraint storage_constraints = 8 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// (-- api-linter: core::0123::resource-annotation=disabled
//     aip.dev/not-precedent: `name` here is a spec label embedded in a constraints payload, not a standalone resource. --)
message ByocSharedComponentScaleRequiredMinSpec {
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 cpu = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 memory_gi = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ByocSharedComponentScaleStorageConstraint {
  string storage_name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  bool resizable = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  int64 current_size_gi = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  optional int64 max_size_gi = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// (-- api-linter: core::0158::response-next-page-token-field=disabled
//     aip.dev/not-precedent: this is a page-style read model that always returns the full grouped inventory. --)
message ListByocVcpuPoolsResponse {
  repeated Group groups = 1;

  message Group {
    common.v1beta1.Region region = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
    // The sum of vcpus_limit across all active organization-owned BYOC pools
    // in the group, regardless of whether dataplane_id is empty.
    int64 total_vcpus_limit = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
    repeated ByocVcpuPool pools = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  }
}

enum NodeSpecComponentType {
  NODE_SPEC_COMPONENT_TYPE_UNSPECIFIED = 0;
  NODE_SPEC_COMPONENT_TYPE_TIKV = 1;
  NODE_SPEC_COMPONENT_TYPE_TIFLASH = 2;
}

enum NodeCountRuleType {
  NODE_COUNT_RULE_TYPE_UNSPECIFIED = 0;
  NODE_COUNT_RULE_TYPE_NONE = 1;
  NODE_COUNT_RULE_TYPE_MULTIPLE_OF = 2;
  NODE_COUNT_RULE_TYPE_FIXED = 3;
}

enum ByocSharedComponentType {
  BYOC_SHARED_COMPONENT_TYPE_UNSPECIFIED = 0;
  BYOC_SHARED_COMPONENT_TYPE_TIKV = 1;
  BYOC_SHARED_COMPONENT_TYPE_TIFLASH_WRITE = 2;
  BYOC_SHARED_COMPONENT_TYPE_TIFLASH_COMPUTE = 3;
}
