syntax = "proto3";

package tidb_mgmt_service.v1;

import "datatype/v1/enums.proto";
import "global/common/v1/resources.proto";
import "google/api/annotations.proto";
import "google/api/field_behavior.proto";
import "protoc-gen-openapiv2/options/annotations.proto";

/**
   All APIs here are for global control plane **internal** use only.
*/

option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
  swagger: "2.0"
  host: ""
  base_path: "/inner/mgmt/v1"
  info: {
    version: "v1"
    title: "Control Plane Internal API"
    description: "Control Plane Internal API."
  }
  schemes: HTTPS
};

service MigrationClusterService {
  rpc CreateMigrationCluster(CreateMigrationClusterRequest) returns (MigrationCluster) {
    option (google.api.http) = {
      post: "/migrationClusters"
      body: "*"
    };
  }

  rpc GetMigrationCluster(GetMigrationClusterRequest) returns (MigrationCluster) {
    option (google.api.http) = {get: "/migrationClusters/{id}"};
  }
}

message MigrationCluster {
  // ID of the migration cluster
  uint64 id = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // ID of the source cluster
  uint64 source_cluster_id = 2 [(google.api.field_behavior) = REQUIRED];

  // ID of the backup of the source cluster
  uint64 backup_id = 3 [(google.api.field_behavior) = OPTIONAL];

  // ID of the target project where the migration cluster will be created
  // If not provided, the migration cluster will be created in the same project as the source cluster
  uint64 target_project_id = 4 [(google.api.field_behavior) = OPTIONAL];

  // Display Name of the migration cluster to be created
  string cluster_display_name = 5 [(google.api.field_behavior) = REQUIRED];

  // Configuration of the TiDB component in the migration cluster
  TidbNodeSetting tidb_node_setting = 6 [(google.api.field_behavior) = OPTIONAL];

  // Configuration of the TiKV component in the migration cluster
  StorageNodeSetting tikv_node_setting = 7 [(google.api.field_behavior) = OPTIONAL];

  // Configuration of the TiFlash component in the migration cluster
  StorageNodeSetting tiflash_node_setting = 8 [(google.api.field_behavior) = OPTIONAL];

  // Configuration of the PD component in the migration cluster
  PdNodeSetting pd_node_setting = 13 [(google.api.field_behavior) = OPTIONAL];

  string br_version = 9 [(google.api.field_behavior) = OPTIONAL];

  // Target version of the migration cluster to be upgraded to
  string target_cluster_version = 10 [(google.api.field_behavior) = OPTIONAL];

  // Current state of the migration cluster provision operation
  State state = 11 [(google.api.field_behavior) = OUTPUT_ONLY];

  // ID of the target cluster created for migration
  uint64 target_cluster_id = 12 [(google.api.field_behavior) = OUTPUT_ONLY];

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

  // Custom options for the BR command
  string br_custom_options = 15 [(google.api.field_behavior) = OPTIONAL];

  // Image tag for the TiDB component in the migration cluster during upgrade
  string tidb_image_tag = 16 [(google.api.field_behavior) = OPTIONAL];
  // Image tag for the TiKV component in the migration cluster during upgrade
  string tikv_image_tag = 17 [(google.api.field_behavior) = OPTIONAL];
  // Image tag for the PD component in the migration cluster during upgrade
  string pd_image_tag = 18 [(google.api.field_behavior) = OPTIONAL];
  // Image tag for the TiFlash component in the migration cluster during upgrade
  string tiflash_image_tag = 19 [(google.api.field_behavior) = OPTIONAL];

  // Image tag for the TiDB component in the migration cluster during creation
  string create_cluster_tidb_image_tag = 20 [(google.api.field_behavior) = OPTIONAL];
  // Image tag for the TiKV component in the migration cluster during creation
  string create_cluster_tikv_image_tag = 21 [(google.api.field_behavior) = OPTIONAL];
  // Image tag for the PD component in the migration cluster during creation
  string create_cluster_pd_image_tag = 22 [(google.api.field_behavior) = OPTIONAL];
  // Image tag for the TiFlash component in the migration cluster during creation
  string create_cluster_tiflash_image_tag = 23 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Defaults to source cluster region.
  // Cross-region clone is only allowed within the same cloud provider.
  global.common.v1.Region.Name target_region_id = 24 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Defaults to SNAPSHOT if unspecified.
  // Users should explicitly choose another restore mode when needed.
  RestoreMode restore_mode = 25 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Defaults to target_region_id if unspecified.
  // The backup region is not required to be the same as target_region_id.
  global.common.v1.Region.Name backup_region_id = 26 [(google.api.field_behavior) = OPTIONAL];

  message TidbNodeSetting {
    string node_spec_key = 1 [(google.api.field_behavior) = OPTIONAL];
    repeated TidbNodeGroup tidb_node_groups = 2 [(google.api.field_behavior) = OPTIONAL];
  }

  message TidbNodeGroup {
    string display_name = 1 [(google.api.field_behavior) = REQUIRED];
    bool is_default_group = 2 [(google.api.field_behavior) = REQUIRED];
    optional int32 node_count = 3 [(google.api.field_behavior) = OPTIONAL];
  }

  message StorageNodeSetting {
    string node_spec_key = 1 [(google.api.field_behavior) = OPTIONAL];
    optional int32 node_count = 2 [(google.api.field_behavior) = OPTIONAL];
  }

  message PdNodeSetting {
    string node_spec_key = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  enum State {
    STATE_UNSPECIFIED = 0;
    PENDING = 1; // Operation is queued and waiting to start
    RUNNING = 2; // Operation is currently executing
    SUCCEEDED = 3; // Operation completed successfully
    FAILED = 4; // Operation failed
  }

  enum RestoreMode {
    MODE_UNSPECIFIED = 0;
    SNAPSHOT = 1 [(datatype.v1.name) = "SNAPSHOT"];
    PITR = 2 [(datatype.v1.name) = "PITR"];
  }
}

message CreateMigrationClusterRequest {
  // Details of the migration cluster to create
  MigrationCluster migration_cluster = 1 [(google.api.field_behavior) = REQUIRED];

  // If true, only validates the request and returns INVALID_ARGUMENT on failure,
  // without creating or starting the operation
  bool validate_only = 2 [(google.api.field_behavior) = OPTIONAL];

  // Strategy that controls how cluster configs are synchronized during migration cluster creation.
  ConfigSyncStrategy config_sync_strategy = 3 [(google.api.field_behavior) = OPTIONAL];
}

message ConfigSyncStrategy {
  // If true, fallback to backup when live config fetch fails.
  bool allow_fallback_to_backup = 1 [(google.api.field_behavior) = OPTIONAL];

  // If true, skip synchronizing system variables.
  bool skip_system_variables = 2 [(google.api.field_behavior) = OPTIONAL];

  // If true, skip synchronizing regular PD config.
  bool skip_pd_config = 3 [(google.api.field_behavior) = OPTIONAL];

  // If true, skip synchronizing PD server config.
  bool skip_pd_server_config = 4 [(google.api.field_behavior) = OPTIONAL];

  // If true, skip synchronizing placement rules.
  bool skip_placement_rules = 5 [(google.api.field_behavior) = OPTIONAL];

  // If true, skip synchronizing store limits.
  bool skip_store_limits = 6 [(google.api.field_behavior) = OPTIONAL];
}

message GetMigrationClusterRequest {
  // ID of the migration cluster to retrieve
  uint64 id = 1 [(google.api.field_behavior) = REQUIRED];
}
