syntax = "proto3";

package tidb_mgmt_service.v1;

import "global/common/v1/resources.proto";
import "global/dedicated/v1/resources.proto";
import "global/nextgen/v1/cluster.proto";
import "global/nextgen/v1/region.proto";
import "global/serverless/v1/resources.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/timestamp.proto";
import "tidb_cloud_open_api/common/v1beta1/clusterstate.proto";
import "tidb_cloud_open_api/common/v1beta1/service_plan.proto";
import "tidb_cloud_open_api/common/v1beta1/tag.proto";
import "tidb_cloud_open_api/dedicated/v1beta1/resources.proto";

// Cluster
message Cluster {
  uint64 cluster_id = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  uint64 project_id = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  uint64 organization_id = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
  string cluster_name = 4 [(google.api.field_behavior) = OUTPUT_ONLY];
  string cloud_provider = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
  DeployType deploy_type = 6 [(google.api.field_behavior) = OUTPUT_ONLY];
  string created_by = 7 [(google.api.field_behavior) = OUTPUT_ONLY];
  string region = 8 [(google.api.field_behavior) = OUTPUT_ONLY];
  // cluster custom status
  repeated ClusterCustomStatus custom_statuses = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // global cluster info
  oneof cluster_info {
    global.dedicated.v1.Cluster dedicated_cluster = 10;
    global.serverless.v1.ServerlessServiceCluster serverless_cluster = 11;
    global.nextgen.v1.Cluster next_gen_cluster = 20;
  }

  // storage_type only for dedicated cluster. Adding this field to dedicated_cluster requires massive proto refactor, just put it here currently.
  tidb_cloud_open_api.dedicated.v1beta1.Cluster.StorageNodeSetting.StorageType tikv_storage_type = 12 [(google.api.field_behavior) = OUTPUT_ONLY];
  optional tidb_cloud_open_api.dedicated.v1beta1.Cluster.StorageNodeSetting.StorageType tiflash_storage_type = 13 [(google.api.field_behavior) = OUTPUT_ONLY];

  tidb_cloud_open_api.common.v1beta1.ServicePlan service_plan = 14 [(google.api.field_behavior) = OUTPUT_ONLY];

  uint64 original_project_id = 15 [(google.api.field_behavior) = OUTPUT_ONLY];

  int32 ru_version = 16 [(google.api.field_behavior) = OUTPUT_ONLY];

  repeated tidb_cloud_open_api.common.v1beta1.Tag tags = 17 [(google.api.field_behavior) = OUTPUT_ONLY];

  map<string, string> labels = 18 [(google.api.field_behavior) = OUTPUT_ONLY];

  PlanReplayerStatus plan_replayer_status = 19 [(google.api.field_behavior) = OUTPUT_ONLY];

  google.protobuf.Timestamp create_time = 100 [(google.api.field_behavior) = OUTPUT_ONLY];
  google.protobuf.Timestamp update_time = 101 [(google.api.field_behavior) = OUTPUT_ONLY];
  optional google.protobuf.Timestamp delete_time = 102 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message PlanReplayerStatus {
  bool enabled = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  google.protobuf.Timestamp expire_time = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
}

message ClusterFilter {
  enum ClusterView {
    // default view is basic
    // because of dedicated not support basic view, so it will return full cluster info
    CLUSTER_VIEW_UNSPECIFIED = 0;

    // only show local cluster info not include cluster_info
    CLUSTER_VIEW_LOCAL = 1;

    // only show basic cluster info. cluster_info is not full
    // dedicated: not display cluster endpoint info and node change progress. not support yet.
    // serverless: not display cluster spending limit and backup policy.
    CLUSTER_VIEW_BASIC = 2;

    // return full cluster info
    CLUSTER_VIEW_FULL = 3; // show all cluster info
  }

  repeated uint64 cluster_ids = 1 [(google.api.field_behavior) = OPTIONAL];
  repeated uint64 project_ids = 2 [(google.api.field_behavior) = OPTIONAL];
  repeated uint64 tenant_ids = 3 [(google.api.field_behavior) = OPTIONAL];
  repeated string cloud_providers = 4 [(google.api.field_behavior) = OPTIONAL];
  repeated string regions = 5 [(google.api.field_behavior) = OPTIONAL];

  repeated tidb_cloud_open_api.common.v1beta1.ClusterState states = 6 [(google.api.field_behavior) = OPTIONAL];
  repeated tidb_cloud_open_api.common.v1beta1.ClusterState exclude_states = 7 [(google.api.field_behavior) = OPTIONAL];

  // Default view is basic
  ClusterView view = 8 [(google.api.field_behavior) = OPTIONAL];

  // Default show all cluster type
  optional DeployType cluster_type = 9 [(google.api.field_behavior) = OPTIONAL];

  // Default show deleted cluster
  optional bool deleted = 10 [(google.api.field_behavior) = OPTIONAL];

  // Default to false
  // Set it to true to list the latest serverless clusters and refresh their caches between serverless-gloabl-svc and serverless-regional-svc.
  // It's useful when you want to fetch the serverless cluster changes which are not triggered by the management service
  // Use it only when you know what you are doing
  bool refresh_cache = 11 [(google.api.field_behavior) = OPTIONAL];

  // If specified, only clusters belonging to the specified service plan will be returned.
  tidb_cloud_open_api.common.v1beta1.ServicePlan service_plan = 12 [(google.api.field_behavior) = OPTIONAL];

  // If specified, clusters belonging to the listed project IDs will be excluded from results.
  repeated uint64 exclude_project_ids = 13 [(google.api.field_behavior) = OPTIONAL];

  repeated string tags = 14 [(google.api.field_behavior) = OPTIONAL];

  // Default to false.
  // This is a compatibility escape hatch for the internal cluster aggregation API.
  // When set to true, dedicated clusters will no longer force non-local views to full view.
  optional bool allow_non_full_view = 15 [(google.api.field_behavior) = OPTIONAL];
}

// ClusterCustom
message ClusterCustomStatus {
  message CustomMutex {
    repeated CustomStatusType status_type = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
    repeated ClusterAction cluster_action = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  uint64 status_id = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  uint64 cluster_id = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  string status_name = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  CustomStatusType status_type = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  optional CustomMutex mutex = 5 [(google.api.field_behavior) = OPTIONAL];

  optional int64 timeout_secs = 6 [(google.api.field_behavior) = OPTIONAL];

  bool is_expired = 7 [(google.api.field_behavior) = OUTPUT_ONLY];

  optional tidb_cloud_open_api.common.v1beta1.ClusterState override_status = 8 [(google.api.field_behavior) = OPTIONAL];
}

enum CustomStatusType {
  CUSTOM_STATUS_TYPE_UNSPECIFIED = 0;
  CUSTOM_STATUS_TYPE_BACKUP = 1;
  CUSTOM_STATUS_TYPE_IMPORT = 2;
  CUSTOM_STATUS_TYPE_CDC = 3;
  CUSTOM_STATUS_TYPE_RESTORE = 4;
  CUSTOM_STATUS_TYPE_SERVERLESS_RESTORE = 5;
  CUSTOM_STATUS_TYPE_MAINTENANCE = 6;
  CUSTOM_STATUS_TYPE_APPLY = 7;
  CUSTOM_STATUS_TYPE_RECOVERY_GROUP = 8;
  CUSTOM_STATUS_TYPE_MODIFYING = 9;
  CUSTOM_STATUS_TYPE_SERVERLESS_RESTORE_TO_NEW = 10;
  CUSTOM_STATUS_TYPE_SERVERLESS_RESTORE_INPLACE = 11;
  CUSTOM_STATUS_TYPE_SERVERLESS_MIGRATION = 12;
  CUSTOM_STATUS_TYPE_SERVERLESS_PRIVATE_LINK_CONNECTION_EXIST = 13;
  CUSTOM_STATUS_TYPE_EXPORT = 14;
  CUSTOM_STATUS_TYPE_DATA_MIGRATION = 15;
  CUSTOM_STATUS_TYPE_PITR = 16;
}

enum ClusterAction {
  CLUSTER_ACTION_UNSPECIFIED = 0;
  CLUSTER_ACTION_DELETE_CLUSTER = 1;
  CLUSTER_ACTION_MODIFY_CLUSTER = 2;
  CLUSTER_ACTION_RESUME_CLUSTER = 3;
  CLUSTER_ACTION_PAUSE_CLUSTER = 4;
  CLUSTER_ACTION_SCALE_CLUSTER = 5;
  CLUSTER_ACTION_SET_ROOT_PASSWORD = 6;
  CLUSTER_ACTION_SET_TRAFFIC_FILTER = 7;
  CLUSTER_ACTION_CREATE_PRIVATE_LINK = 8;
  CLUSTER_ACTION_CREATE_VPC_PEERING = 9;
  CLUSTER_ACTION_DELETE_VPC_PEERING = 10;
}

message Region {
  global.common.v1.Region region = 1 [(google.api.field_behavior) = OPTIONAL];
  DeployType deploy_type = 2 [(google.api.field_behavior) = OPTIONAL];
  repeated global.nextgen.v1.RegionProviderIdentity region_provider_identities = 3 [(google.api.field_behavior) = OPTIONAL];
  repeated global.nextgen.v1.DefaultRegionProviderIdentity default_provider_identities = 4 [(google.api.field_behavior) = OPTIONAL];
}

message CloudProvider {
  global.common.v1.CloudProvider cloud_provider = 1 [(google.api.field_behavior) = OPTIONAL];
  DeployType deploy_type = 2 [(google.api.field_behavior) = OPTIONAL];
}

// deploy type
enum DeployType {
  DEPLOY_TYPE_UNSPECIFIED = 0; // default show all clusters
  DEPLOY_TYPE_DEDICATED = 1;
  DEPLOY_TYPE_SERVERLESS = 2;
  DEPLOY_TYPE_NEXTGEN = 3;
}

// Message for serverless auto scaling configuration.
message AutoScaling {
  uint32 min_rcu = 1 [(google.api.field_behavior) = OPTIONAL];
  uint32 max_rcu = 2 [(google.api.field_behavior) = OPTIONAL];
}

message CloudIamInfo {
  string cluster_id = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // provider iam id
  string tidb_cloud_account_id = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // tidbCloudAccountExternalId
  string tidb_cloud_account_external_id = 3 [(google.api.field_behavior) = OUTPUT_ONLY];

  global.common.v1.CloudProvider cloud_provider = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  global.common.v1.Region region = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The node role or identity used to grant storage access.
  // For Azure, this is the kubelet identity object ID.
  string node_role = 6 [(google.api.field_behavior) = OUTPUT_ONLY];
}
