syntax = "proto3";

package regional.serverless.v1;

// TODO: move to base definition
enum CloudProvider {
  CLOUD_PROVIDER_UNSPECIFIED = 0;
  CLOUD_PROVIDER_AWS = 1;
  CLOUD_PROVIDER_GCP = 2;
  CLOUD_PROVIDER_AZURE = 3;
  CLOUD_PROVIDER_ALICLOUD = 4;
}

// TODO: move to base definition
message Region {
  string name = 1;
  string display_name = 2;
  CloudProvider cloud_provider = 3;
}

// TODO: move to base definition
message PublicEndpoint {
  string host = 1;
  int64 port = 2;
  bool disabled = 3;
  message AuthorizedNetwork {
    string start_ip_address = 1;
    string end_ip_address = 2;
    string display_name = 3;
  }
  repeated AuthorizedNetwork authorized_network = 5;
}

// TODO: move to base definition
message AwsPrivateEndpoint {
  string service_name = 1;
  repeated string availability_zone = 2;
}
message GcpPrivateEndpoint {
  string target_service_attachment = 1;
  string availability_zone = 2;
}
message AlicloudPrivateEndpoint {
  string service_name = 1;
  repeated string availability_zone = 2;
}
message PrivateEndpoint {
  string host = 1;
  int64 port = 2;
  bool disabled = 3;
  message AuthorizedNetwork {
    string vpc_endpoint_id = 1;
    string display_name = 2;
  }
  // TODO: TBD: this field is redundant with the cluster's, remove it ?
  CloudProvider cloud_provider = 4;
  oneof private_endpoint {
    AwsPrivateEndpoint aws = 5;
    GcpPrivateEndpoint gcp = 6;
    // AzurePrivateEndpoint azure = 7;
    AlicloudPrivateEndpoint alicloud = 8;
  }
  repeated AuthorizedNetwork authorized_network = 9;
}
message Endpoints {
  PublicEndpoint public = 1;
  PrivateEndpoint private = 2;
}

// These is the regional related cluster status info, not the same with global
// definition
enum ClusterState {
  CLUSTER_STATE_UNSPECIFIED = 0;
  // The cluster can be accessed only when it is `READY`
  CLUSTER_STATE_READY = 1;
  CLUSTER_STATE_CREATING = 2;
  CLUSTER_STATE_DELETING = 3;
  CLUSTER_STATE_DELETED = 4;
}

message ServerlessRegionalServiceClusterInfo {
  // The cluster-id should equal to the request one
  string cluster_id = 1;

  // The creating request timestamp
  int64 create_ts = 2;
  // The creating finished timestamp
  int64 created_ts = 3;
  // The deleting request timestamp
  int64 delete_ts = 4;
  // The most recent status updated timestamp
  int64 updated_ts = 5;

  uint64 tenant_id = 6;

  uint64 project_id = 7;

  // The cluster version
  string version = 8;
  // The cluster region
  Region region = 9;
  // The cluster endpoints
  Endpoints endpoints = 10;

  ClusterState state = 11;

  string user_prefix = 12;

  string proxy_endpoint = 13;

  bool token_based_auth_enabled = 14;

  bool enhanced_encryption_enabled = 15;

  bool restore_cluster = 16;

  bool zone_redundant_enabled = 17;

  string kubernetes = 18;

  string provider_type = 19;

  AuditLogConfig audit_log_config = 20;

  uint32 keyspace_id = 21;

  // The underlying regional cluster annotations, originally from the cluster cr
  map<string, string> annotations = 22;

  message AuditLogConfig {
    optional bool enabled = 1;
    optional bool unredacted = 2;
    CloudStorage cloud_storage = 3;
    optional int64 rotation_interval_seconds = 4; // The rotation interval in seconds
    optional int64 rotation_size_bytes = 5; // The rotation size in bytes
  }

  message AutoScaling {
    uint32 min_rcu = 1;
    uint32 max_rcu = 2;
  }

  AutoScaling auto_scaling = 23;

  // TODO: updating status, should not in ClusterState
}

message CloudStorage {
  CloudStorageType cloud_storage_type = 1;
  oneof cloud_storage {
    S3CloudStorage s3 = 2;

    GCSCloudStorage gcs = 3;

    AzureBlobCloudStorage azure_blob = 4;

    S3CompatibleCloudStorage s3_compatible = 5;

    OSSCloudStorage oss = 6;
  }
  string uri = 7; // The URI of the cloud storage data dir.
}

enum CloudStorageType {
  CLOUD_STORAGE_TYPE_UNSPECIFIED = 0;
  S3 = 1;
  GCS = 2;
  AZURE_BLOB = 3;
  OSS = 4;
  S3_COMPATIBLE = 5; // S3 compatible storage
  INTERNAL = 6; // Internal source storage, no authentication required
}

message S3CloudStorage {
  AuthType auth_type = 1;

  oneof auth {
    // The role arn
    RoleArn role_arn = 2;
    // The access key.
    AccessKey access_key = 3;
  }

  enum AuthType {
    AUTH_TYPE_UNSPECIFIED = 0;
    ROLE_ARN = 1; // Use role ARN to access S3
    ACCESS_KEY = 2; // Use access key and secret access key to access S3
  }

  message RoleArn {
    string role_arn = 1; // The role ARN to access S3
    string external_id = 2; // The external ID to access S3
  }

  message AccessKey {
    string access_key_id = 1; // The access key ID to access S3
    string secret_access_key = 2; // The secret access key to access S3
  }
}

message GCSCloudStorage {
  AuthType auth_type = 1;

  oneof auth {
    string service_account_key = 2;
  }

  enum AuthType {
    AUTH_TYPE_UNSPECIFIED = 0;
    SERVICE_ACCOUNT_KEY = 1; // Use service account key to access GCS
  }
}

message AzureBlobCloudStorage {
  AuthType auth_type = 1;

  oneof auth {
    string sas_token = 2; // The SAS token to access Azure Blob Storage
  }

  enum AuthType {
    AUTH_TYPE_UNSPECIFIED = 0;
    SAS_TOKEN = 1; // Use SAS token to access Azure Blob Storage
  }
}

message OSSCloudStorage {
  AuthType auth_type = 1;

  oneof auth {
    // The role arn
    RoleArn role_arn = 2;
    AccessKey access_key = 3; // The access key to access OSS
  }

  enum AuthType {
    AUTH_TYPE_UNSPECIFIED = 0;
    ROLE_ARN = 1; // Use role ARN to access OSS
    ACCESS_KEY = 2; // Use access key and secret access key to access OSS
  }

  message AccessKey {
    string access_key_id = 1; // The access key ID to access OSS
    string access_key_secret = 2; // The access key secret to access OSS
  }

  message RoleArn {
    string role_arn = 1; // The role ARN to access OSS
    string external_id = 2; // The external ID to access OSS
  }
}

message S3CompatibleCloudStorage {
  AuthType auth_type = 1;

  oneof auth {
    AccessKey access_key = 2; // The access key to access S3 compatible storage
  }

  string endpoint = 3; // The endpoint of the S3 compatible storage

  enum AuthType {
    AUTH_TYPE_UNSPECIFIED = 0;
    ACCESS_KEY = 1; // Use access key and secret access key to access S3 compatible storage
  }

  message AccessKey {
    string access_key_id = 1; // The access key ID to access S3 compatible storage
    string secret_access_key = 2; // The secret access key to access S3 compatible storage
  }
}

message DatabaseCredential {
  string user_name = 1;
  string credential = 2; // password or auth token
}

message FileRouteRule {
  string pattern = 1;
  string schema = 2;
  string table = 3;
  string type = 4;
}

message TableResult {
  repeated string data_files = 1;
  string schema_file = 2;
  Table table = 3;
  string error_msg = 4;
  bool use_schema_file = 5; // If true, the schema_file is used to create the table
}

message Table {
  string schema = 1;
  string table = 2;
}

message BaseResp {
  int64 err_code = 1;
  string err_msg = 2;
}

enum ImportPrecheckStatus {
  // The precheck status is unknown.
  IMPORT_PRECHECK_STATUS_UNSPECIFIED = 0;

  // The precheck is completed.
  COMPLETED = 1;

  // The precheck is timeout and return partial result.
  TIMEOUT = 2;

  // The precheck result is truncated.
  TRUNCATED = 3;
}

message DMPrecheck {
  repeated Source sources = 1;
  TargetDatabase target_db = 2;
  TaskMode mode = 3;
  bool full_instance_migration = 4;
  PrecheckItem item = 5;

  enum PrecheckItem {
    PRECHECK_ITEM_UNSPECIFIED = 0;
    PRECHECK_ITEM_DUMP_PRIVILEGE_CHECKING = 1;
    PRECHECK_ITEM_REPLICATION_PRIVILEGE_CHECKING = 2;
    PRECHECK_ITEM_VERSION_CHECKING = 3;
    PRECHECK_ITEM_SERVER_ID_CHECKING = 4;
    PRECHECK_ITEM_BINLOG_ENABLE_CHECKING = 5;
    PRECHECK_ITEM_BINLOG_FORMAT_CHECKING = 6;
    PRECHECK_ITEM_BINLOG_ROW_IMAGE_CHECKING = 7;
    PRECHECK_ITEM_TABLE_SCHEMA_CHECKING = 8;
    PRECHECK_ITEM_BINLOG_DB_CHECKING = 9;
    PRECHECK_ITEM_CONN_NUMBER_CHECKING = 10;
    PRECHECK_ITEM_TARGET_DB_PRIVILEGE_CHECKING = 11;
    PRECHECK_ITEM_META_POSITION_CHECKING = 12;
    PRECHECK_ITEM_PRIMARY_KEY_CHECKING = 13;
  }

  message TargetDatabase {
    string host = 1;
    int32 port = 2;
    string user = 3;
    string password = 4;
  }

  message BlockAllowRules {
    repeated string do_dbs = 1;
    repeated Table do_tables = 2;
    // support blocklist in the future
    // repeated string ignore_dbs = 3;
    // repeated Table ignore_tables = 4;
  }

  message Source {
    ConnProfile conn_profile = 1;
    optional BlockAllowRules rules = 2;
    optional string binlog_name = 3;
    optional int32 binlog_pos = 4;
    optional string binlog_gtid = 5;
    bool need_pk_check = 6;
    repeated TableRouteRule route_rules = 7;
  }

  message TableRouteRule {
    string schema_pattern = 1;
    string table_pattern = 2;
    string target_schema = 3;
    string target_table = 4;
  }

  message ConnProfile {
    string host = 1;
    int32 port = 2;
    string user = 3;
    string password = 4;
    Security security = 5; // optional, if not set, use default
  }

  message Security {
    repeated string cert_allowed_cn = 1;
    bytes ssl_ca_content = 2;
    bytes ssl_cert_content = 3;
    bytes ssl_key_content = 4;
  }

  enum TaskMode {
    TASK_MODE_UNSPECIFIED = 0;
    TASK_MODE_ALL = 1;
    TASK_MODE_INCREMENTAL = 2;
  }
}

message VpcEndpointDetails {
  string endpoint_id = 1;
  string service_name = 2;
  VpcEndpointState state = 3;
  string vpc_id = 4;
  string creation_timestamp = 5;
  string domain = 6;

  ProviderType type = 7;
  enum ProviderType {
    TYPE_UNSPECIFIED = 0;
    TYPE_ALICLOUD = 1;
  }

  oneof detail {
    AlicloudDetail alicloud = 8;
  }
  message AlicloudDetail {
    string endpoint_state = 9;
    string connection_state = 10;
  }
}

// VpcEndpointState represents the lifecycle state of a VPC endpoint.
enum VpcEndpointState {
  VPC_ENDPOINT_STATE_UNSPECIFIED = 0;
  // The endpoint is being created or configured. Users should continue polling until it becomes Active.
  VPC_ENDPOINT_STATE_NOT_READY = 1;
  // The endpoint is ready and can be used by users.
  VPC_ENDPOINT_STATE_ACTIVE = 2;
  // The endpoint has been successfully deleted.
  VPC_ENDPOINT_STATE_DELETED = 3;
  // The endpoint is in an unrecoverable state. Users need to create a new endpoint.
  VPC_ENDPOINT_STATE_FAILED = 4;
  // The endpoint is pending approval.
  VPC_ENDPOINT_STATE_PENDING_APPROVE = 5;
  // The endpoint is not connected.
  VPC_ENDPOINT_STATE_NOT_CONNECTED = 6;
}

// Details of a VPC endpoint zone
message VpcEndpointZone {
  string zone_id = 1;
  // The state of the zone (e.g. Creating, Wait, Connected, Deleting, Disconnecting, Disconnected, Connecting)
  string zone_status = 2;
}

message AWSVpcEndpoint {
  string endpoint_id = 1;
  string endpoint_service_name = 2;
  string endpoint_service_region = 3;
  AWSVpcEndpointState.Enum state = 4;
  string vpc_id = 5;
  int64 create_ts = 6;
  repeated string domains = 7;
  string failure_message = 8;
  // A map of availability zone ID to availability zone name
  map<string, string> available_zones = 9;
}

message AWSVpcEndpointState {
  enum Enum {
    _UNSPECIFIED = 0;
    PENDING = 1;
    PENDING_ACCEPTANCE = 2;
    REJECTED = 3;
    EXPIRED = 4;
    FAILED = 5;
    DELETED = 6;
    DELETING = 7;
    AVAILABLE = 8;
  }
}

message AliCloudVpcEndpoint {
  string endpoint_id = 1;
  string endpoint_service_name = 2;
  AliCloudVpcEndpointState.Enum state = 3;
  AliCloudVpcEndpointConnectionState.Enum connection_state = 4;
  string vpc_id = 5;
  int64 create_ts = 6;
  string domain = 7;
}

message AliCloudVpcEndpointZone {
  string zone_id = 1;
  // The state of the zone (e.g. Creating, Wait, Connected, Deleting, Disconnecting, Disconnected, Connecting)
  string zone_status = 2;
}

message AliCloudVpcEndpointState {
  enum Enum {
    _UNSPECIFIED = 0;
    PENDING = 1;
    CREATING = 2;
    ACTIVE = 3;
    DELETING = 4;
  }
}

message AliCloudVpcEndpointConnectionState {
  enum Enum {
    _UNSPECIFIED = 0;
    CONNECTING = 1;
    PENDING = 2;
    CONNECTED = 3;
    DISCONNECTED = 4;
    DISCONNECTING = 5;
    DELETING = 6;
  }
}

message Route53ChangeState {
  enum Enum {
    _UNSPECIFIED = 0;
    PENDING = 1;
    INSYNC = 2;
  }
}

message MSKVpcConnectionState {
  enum Enum {
    _UNSPECIFIED = 0;
    CREATING = 1;
    AVAILABLE = 2;
    INACTIVE = 3;
    DEACTIVATING = 4;
    DELETING = 5;
    FAILED = 6;
    REJECTED = 7;
    REJECTING = 8;
  }
}

message MSKVpcConnection {
  string msk_arn = 1;
  string msk_vpc_connection_arn = 2;
  MSKVpcConnectionState.Enum state = 3;
  string bootstrap_broker = 4;
  // A map of availability zone ID to availability zone name
  map<string, string> available_zones = 5;
}
