syntax = "proto3";

package regional.serverless.v1;

import "google/api/annotations.proto";
import "protoc-gen-openapiv2/options/annotations.proto";
import "regional/serverless/v1/resources.proto";

// These annotations are used when generating the OpenAPI file.
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
  info: {version: "2.0"}
  external_docs: {
    url: "TODO: Add URL"
    description: "TODO: Add description"
  }
  schemes: HTTPS
};

service ServerlessRegionalService {
  // Self description
  rpc DescRegion(ServerlessRegionalServiceDescRegionRequest) returns (ServerlessRegionalServiceDescRegionResponse) {
    option (google.api.http) = {get: "/serverless/regional/v1/desc"};
  }

  // Clusters CRUD
  rpc CreateCluster(ServerlessRegionalServiceCreateClusterRequest) returns (ServerlessRegionalServiceCreateClusterResponse) {
    option (google.api.http) = {
      // TODO: TBD: path prefix
      post: "/serverless/regional/v1/clusters/{cluster_id}"
      body: "*"
    };
  }
  rpc GetCluster(ServerlessRegionalServiceGetClusterRequest) returns (ServerlessRegionalServiceGetClusterResponse) {
    option (google.api.http) = {get: "/serverless/regional/v1/clusters/{cluster_id}"};
  }
  rpc ListClusters(ServerlessRegionalServiceListClustersRequest) returns (ServerlessRegionalServiceListClustersResponse) {
    option (google.api.http) = {
      get: "/serverless/regional/v1/clusters"
      // TODO: TBD: page_size | page-size | pageSize ?
      // TODO: how to define:
      // "?page={page}&page-size={page_size}&show-deleted={show_deleted}"
    };
  }
  rpc UpdateCluster(ServerlessRegionalServiceUpdateClusterRequest) returns (ServerlessRegionalServiceUpdateClusterResponse) {
    option (google.api.http) = {
      patch: "/serverless/regional/v1/clusters/{cluster_id}"
      body: "*"
    };
  }
  rpc DeleteCluster(ServerlessRegionalServiceDeleteClusterRequest) returns (ServerlessRegionalServiceDeleteClusterResponse) {
    option (google.api.http) = {delete: "/serverless/regional/v1/clusters/{cluster_id}"};
  }

  rpc CheckCloudStoragePermission(CheckCloudStoragePermissionRequest) returns (CheckCloudStoragePermissionResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/clusters:checkCloudStoragePermission"
      body: "*"
    };
  }

  // TODO: Sql users
  // rpc GetCloudAdminPwd
  // rpc CreateSqlUser
  // rpc GetSqlUser
  // rpc UpdateSqlUser
  // rpc DeleteSqlUser
}

service ServerlessImportRegionalService {
  rpc CheckImportPermission(CheckImportPermissionRequest) returns (CheckImportPermissionResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/import:checkPermission"
      body: "*"
    };
  }

  rpc Precheck(PrecheckRequest) returns (PrecheckResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/import:precheck"
      body: "*"
    };
  }
}

service ServerlessDMRegionalService {
  rpc Precheck(ServerlessDMRegionalServicePrecheckRequest) returns (ServerlessDMRegionalServicePrecheckResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/dm:precheck"
      body: "*"
    };
  }
  rpc CreateVpcEndpoint(CreateVpcEndpointRequest) returns (CreateVpcEndpointResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/dm:createVpcEndpoint"
      body: "*"
    };
  }

  rpc DescribeVpcEndpoint(DescribeVpcEndpointRequest) returns (DescribeVpcEndpointResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/dm:describeVpcEndpoint"
      body: "*"
    };
  }

  rpc DeleteVpcEndpoint(DeleteVpcEndpointRequest) returns (DeleteVpcEndpointResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/dm:deleteVpcEndpoint"
      body: "*"
    };
  }

  // List zones of a VPC endpoint
  rpc ListVpcEndpointZones(ListVpcEndpointZonesRequest) returns (ListVpcEndpointZonesResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/dm:listVpcEndpointZones"
      body: "*"
    };
  }

  // Remove a zone from a VPC endpoint
  rpc RemoveZoneFromVpcEndpoint(RemoveZoneFromVpcEndpointRequest) returns (RemoveZoneFromVpcEndpointResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/dm:removeZoneFromVpcEndpoint"
      body: "*"
    };
  }
}

service ServerlessPrivateLinkConnectionRegionalService {
  rpc CreateAWSVpcEndpoint(CreateAWSVpcEndpointRequest) returns (CreateAWSVpcEndpointResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:createAWSVpcEndpoint"
      body: "*"
    };
  }

  rpc DescribeAWSVpcEndpoint(DescribeAWSVpcEndpointRequest) returns (DescribeAWSVpcEndpointResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:describeAWSVpcEndpoint"
      body: "*"
    };
  }

  rpc DeleteAWSVpcEndpoint(DeleteAWSVpcEndpointRequest) returns (DeleteAWSVpcEndpointResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:deleteAWSVpcEndpoint"
      body: "*"
    };
  }

  rpc CreateAliCloudVpcEndpoint(CreateAliCloudVpcEndpointRequest) returns (CreateAliCloudVpcEndpointResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:createAliCloudVpcEndpoint"
      body: "*"
    };
  }

  rpc DescribeAliCloudVpcEndpoint(DescribeAliCloudVpcEndpointRequest) returns (DescribeAliCloudVpcEndpointResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:describeAliCloudVpcEndpoint"
      body: "*"
    };
  }

  rpc DeleteAliCloudVpcEndpoint(DeleteAliCloudVpcEndpointRequest) returns (DeleteAliCloudVpcEndpointResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:deleteAliCloudVpcEndpoint"
      body: "*"
    };
  }

  rpc GetZoneIds(GetZoneIdsRequest) returns (GetZoneIdsResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:getZoneIds"
      body: "*"
    };
  }

  // List zones of a VPC endpoint
  rpc ListAliCloudVpcEndpointZones(ListAliCloudVpcEndpointZonesRequest) returns (ListAliCloudVpcEndpointZonesResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:listAliCloudVpcEndpointZones"
      body: "*"
    };
  }

  // Remove a zone from a VPC endpoint
  rpc RemoveAliCloudZoneFromVpcEndpoint(RemoveAliCloudZoneFromVpcEndpointRequest) returns (RemoveAliCloudZoneFromVpcEndpointResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:removeZoneFromAliCloudVpcEndpoint"
      body: "*"
    };
  }

  rpc CreateAliCloudDNSRecord(CreateAliCloudDNSRecordRequest) returns (CreateAliCloudDNSRecordResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:createAliCloudDNSRecord"
      body: "*"
    };
  }

  rpc DeleteAliCloudDNSRecord(DeleteAliCloudDNSRecordRequest) returns (DeleteAliCloudDNSRecordResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:deleteAliCloudDNSRecord"
      body: "*"
    };
  }

  rpc CreateAWSRoute53Records(CreateAWSRoute53RecordsRequest) returns (CreateAWSRoute53RecordsResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:createAWSRoute53Records"
      body: "*"
    };
  }

  rpc DeleteAWSRoute53Records(DeleteAWSRoute53RecordsRequest) returns (DeleteAWSRoute53RecordsResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:deleteAWSRoute53Records"
      body: "*"
    };
  }

  rpc GetAWSRoute53Change(GetAWSRoute53ChangeRequest) returns (GetAWSRoute53ChangeResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:getAWSRoute53Change"
      body: "*"
    };
  }

  rpc CreateAWSRoute53PrivateHostedZone(CreateAWSRoute53PrivateHostedZoneRequest) returns (CreateAWSRoute53PrivateHostedZoneResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:createAWSRoute53PrivateHostedZone"
      body: "*"
    };
  }

  rpc DeleteAWSRoute53PrivateHostedZone(DeleteAWSRoute53PrivateHostedZoneRequest) returns (DeleteAWSRoute53PrivateHostedZoneResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:deleteAWSRoute53PrivateHostedZone"
      body: "*"
    };
  }

  rpc CreateAliCloudDNSPrivateHostedZone(CreateAliCloudDNSPrivateHostedZoneRequest) returns (CreateAliCloudDNSPrivateHostedZoneResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:createAliCloudDNSPrivateHostedZone"
      body: "*"
    };
  }

  rpc DeleteAliCloudDNSPrivateHostedZone(DeleteAliCloudDNSPrivateHostedZoneRequest) returns (DeleteAliCloudDNSPrivateHostedZoneResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:deleteAliCloudDNSPrivateHostedZone"
      body: "*"
    };
  }

  rpc AttachVpcToAliCloudDNSPrivateHostedZone(AttachVpcToAliCloudDNSPrivateHostedZoneRequest) returns (AttachVpcToAliCloudDNSPrivateHostedZoneResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:attachVpcToAliCloudDNSPrivateHostedZone"
      body: "*"
    };
  }

  rpc DetachVpcFromAliCloudDNSPrivateHostedZone(DetachVpcFromAliCloudDNSPrivateHostedZoneRequest) returns (DetachVpcFromAliCloudDNSPrivateHostedZoneResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:detachVpcFromAliCloudDNSPrivateHostedZone"
      body: "*"
    };
  }

  rpc CreateMSKVPCConnection(CreateMSKVPCConnectionRequest) returns (CreateMSKVPCConnectionResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:createMSKVPCConnection"
      body: "*"
    };
  }

  rpc DeleteMSKVPCConnection(DeleteMSKVPCConnectionRequest) returns (DeleteMSKVPCConnectionResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:deleteMSKVPCConnection"
      body: "*"
    };
  }

  rpc GetMSKVPCConnection(GetMSKVPCConnectionRequest) returns (GetMSKVPCConnectionResponse) {
    option (google.api.http) = {
      post: "/serverless/regional/v1/privateLinkConnection:getMSKVPCConnection"
      body: "*"
    };
  }
}

message ServerlessDMRegionalServicePrecheckRequest {
  DMPrecheck dm_precheck = 1;
}

message ServerlessDMRegionalServicePrecheckResponse {
  bytes result = 1;
  BaseResp base_resp = 2;
}

message PrecheckRequest {
  CloudStorage cloud_storage = 1;
  DatabaseCredential db_credential = 2;
  repeated FileRouteRule file_route_rules = 3;
  bool use_custom_file_mapping = 4;
}

message PrecheckResponse {
  repeated TableResult table_results = 1;
  ImportPrecheckStatus status = 2;
  BaseResp base_resp = 3;
}

message CheckImportPermissionRequest {
  CloudStorage cloud_storage = 1;
}

message CheckImportPermissionResponse {
  BaseResp base_resp = 1;
}

message ServerlessRegionalServiceDescRegionRequest {}

message ServerlessRegionalServiceDescRegionResponse {
  // TODO: TBD: use nested style?
  // Region region = 1;
  string name = 1;
  string display_name = 2;
  CloudProvider cloud_provider = 3;
}

message ServerlessRegionalServiceCreateClusterRequest {
  // The cluster-id is pre-created before cluster in global
  string cluster_id = 1;
  uint64 project_id = 2;
  uint64 tenant_id = 3;
  Endpoints endpoints = 4;
  bool enhanced_encryption_enabled = 5;
  bool restore_cluster = 6;
  bool zone_redundant_enabled = 7;
  ServerlessRegionalServiceClusterInfo.AuditLogConfig audit_log_config = 8;
  string kubernetes = 9;
  ServerlessRegionalServiceClusterInfo.AutoScaling auto_scaling = 10;
  map<string, string> annotations = 11;

  // TODO:
  // optional string root_sql_user_pwd = 2;
}

message ServerlessRegionalServiceCreateClusterResponse {
  ServerlessRegionalServiceClusterInfo cluster = 1;
}

message ServerlessRegionalServiceGetClusterRequest {
  string cluster_id = 1;
  uint64 project_id = 2;
}

// TODO: TBD: use nested style?
// Same as CreateClusterResponse
message ServerlessRegionalServiceGetClusterResponse {
  ServerlessRegionalServiceClusterInfo cluster = 1;
}

// TODO: TBD: base 0 | 1 ? (currently base 0)
message ServerlessRegionalServiceListClustersRequest {
  int64 page = 1 [json_name = "page"];
  int64 page_size = 2 [json_name = "page_size"];
  repeated ClusterState states = 3 [json_name = "states"];
  //  repeated ClusterState exclude_states = 5;
  repeated string cluster_ids = 4 [json_name = "cluster_ids"];
  repeated uint64 project_ids = 5 [json_name = "project_ids"];
}

message ServerlessRegionalServiceListClustersResponse {
  repeated ServerlessRegionalServiceClusterInfo clusters = 1;
}

// TODO: TBD: use nested style?
message ServerlessRegionalServiceUpdateClusterRequest {
  string cluster_id = 1;
  Endpoints endpoints = 2;
  uint64 project_id = 3;
  map<string, string> annotations = 4;
  ServerlessRegionalServiceClusterInfo.AuditLogConfig audit_log_config = 5;
  ServerlessRegionalServiceClusterInfo.AutoScaling auto_scaling = 6;
}

message ServerlessRegionalServiceUpdateClusterResponse {
  ServerlessRegionalServiceClusterInfo cluster = 1;
}

message ServerlessRegionalServiceDeleteClusterRequest {
  string cluster_id = 1;
  uint64 tenant_id = 2;
  uint64 project_id = 3;
}

// TODO: TBD: use nested style?
message ServerlessRegionalServiceDeleteClusterResponse {
  ServerlessRegionalServiceClusterInfo cluster = 1;
}

message CheckCloudStoragePermissionRequest {
  string cluster_id = 1;
  CloudStorage cloud_storage = 2;
  FeatureName feature_name = 3;

  enum FeatureName {
    FEATURE_NAME_UNSPECIFIED = 0;
    DATABASE_AUDIT_LOG = 1;
    EXPORT = 2;
    CHANGEFEED = 3;
  }
}

message CheckCloudStoragePermissionResponse {
  BaseResp base_resp = 1;
}

message CreateVpcEndpointRequest {
  string service_name = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message CreateVpcEndpointResponse {
  VpcEndpointDetails endpoint_details = 1;
  BaseResp base_resp = 2;
}

message DescribeVpcEndpointRequest {
  string endpoint_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message DescribeVpcEndpointResponse {
  VpcEndpointDetails endpoint_details = 1;
  BaseResp base_resp = 2;
}

message DeleteVpcEndpointRequest {
  string endpoint_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message DeleteVpcEndpointResponse {
  BaseResp base_resp = 1;
}

message ListVpcEndpointZonesRequest {
  string endpoint_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message ListVpcEndpointZonesResponse {
  repeated VpcEndpointZone zones = 1;
  BaseResp base_resp = 2;
}

message RemoveZoneFromVpcEndpointRequest {
  string endpoint_id = 1;
  string zone_id = 2;
  uint64 project_id = 3;
  string cluster_id = 4;
}

message RemoveZoneFromVpcEndpointResponse {
  BaseResp base_resp = 1;
}

// The following messages are for Private Link Connection service
message CreateAWSVpcEndpointRequest {
  string endpoint_service_name = 1;
  // optional, use it when you want to connect to cross-region endpoint service
  string endpoint_service_region = 2;
  uint64 project_id = 3;
  string cluster_id = 4;
}

message CreateAWSVpcEndpointResponse {
  AWSVpcEndpoint endpoint = 1;
  BaseResp base_resp = 2;
}

message DescribeAWSVpcEndpointRequest {
  string endpoint_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message DescribeAWSVpcEndpointResponse {
  AWSVpcEndpoint endpoint = 1;
  BaseResp base_resp = 2;
}

message DeleteAWSVpcEndpointRequest {
  string endpoint_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message DeleteAWSVpcEndpointResponse {
  BaseResp base_resp = 1;
}

message CreateAliCloudVpcEndpointRequest {
  string endpoint_service_name = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message CreateAliCloudVpcEndpointResponse {
  AliCloudVpcEndpoint endpoint = 1;
  BaseResp base_resp = 2;
}

message DescribeAliCloudVpcEndpointRequest {
  string endpoint_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message DescribeAliCloudVpcEndpointResponse {
  AliCloudVpcEndpoint endpoint = 1;
  BaseResp base_resp = 2;
}

message DeleteAliCloudVpcEndpointRequest {
  string endpoint_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message DeleteAliCloudVpcEndpointResponse {
  BaseResp base_resp = 1;
}

message GetZoneIdsRequest {
  uint64 project_id = 1;
  string cluster_id = 2;
  string kubernetes = 4;
}

message GetZoneIdsResponse {
  repeated string zone_ids = 1;
  BaseResp base_resp = 2;
  string account_id = 3;
}

message ListAliCloudVpcEndpointZonesRequest {
  string endpoint_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message ListAliCloudVpcEndpointZonesResponse {
  repeated AliCloudVpcEndpointZone zones = 1;
  BaseResp base_resp = 2;
}

message RemoveAliCloudZoneFromVpcEndpointRequest {
  string endpoint_id = 1;
  string zone_id = 2;
  uint64 project_id = 3;
  string cluster_id = 4;
}

message RemoveAliCloudZoneFromVpcEndpointResponse {
  BaseResp base_resp = 1;
}

message CreateAliCloudDNSRecordRequest {
  string record = 1;
  string value = 2;
  // only used by tidb cloud managed hosted zone
  string hosted_zone_name = 3;
  string hosted_zone_id = 4;
}

message CreateAliCloudDNSRecordResponse {
  int64 record_id = 1;
  BaseResp base_resp = 2;
}

message DeleteAliCloudDNSRecordRequest {
  int64 record_id = 1;
}

message DeleteAliCloudDNSRecordResponse {
  BaseResp base_resp = 1;
}

message CreateAWSRoute53RecordsRequest {
  map<string, string> records = 1;
  // only used by tidb cloud managed hosted zone
  string hosted_zone_name = 2;
  string hosted_zone_id = 3;
}

message CreateAWSRoute53RecordsResponse {
  string change_id = 1;
  BaseResp base_resp = 2;
}

message DeleteAWSRoute53RecordsRequest {
  map<string, string> records = 1;
  // only used by tidb cloud managed hosted zone
  string hosted_zone_name = 2;
  string hosted_zone_id = 3;
}

message DeleteAWSRoute53RecordsResponse {
  string change_id = 1;
  BaseResp base_resp = 2;
}

message GetAWSRoute53ChangeRequest {
  string change_id = 1;
}

message GetAWSRoute53ChangeResponse {
  string change_id = 1;
  Route53ChangeState.Enum state = 2;
  BaseResp base_resp = 3;
}

message CreateAWSRoute53PrivateHostedZoneRequest {
  string hosted_zone_name = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message CreateAWSRoute53PrivateHostedZoneResponse {
  string hosted_zone_id = 1;
  BaseResp base_resp = 2;
}

message DeleteAWSRoute53PrivateHostedZoneRequest {
  string hosted_zone_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message DeleteAWSRoute53PrivateHostedZoneResponse {
  BaseResp base_resp = 1;
}

message CreateAliCloudDNSPrivateHostedZoneRequest {
  string hosted_zone_name = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message CreateAliCloudDNSPrivateHostedZoneResponse {
  string hosted_zone_id = 1;
  BaseResp base_resp = 2;
}

message DeleteAliCloudDNSPrivateHostedZoneRequest {
  string hosted_zone_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message DeleteAliCloudDNSPrivateHostedZoneResponse {
  BaseResp base_resp = 1;
}

message AttachVpcToAliCloudDNSPrivateHostedZoneRequest {
  string hosted_zone_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message AttachVpcToAliCloudDNSPrivateHostedZoneResponse {
  BaseResp base_resp = 1;
}

message DetachVpcFromAliCloudDNSPrivateHostedZoneRequest {
  string hosted_zone_id = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
}

message DetachVpcFromAliCloudDNSPrivateHostedZoneResponse {
  BaseResp base_resp = 1;
}

message CreateMSKVPCConnectionRequest {
  string msk_arn = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
  string kubernetes = 4;
}

message CreateMSKVPCConnectionResponse {
  MSKVpcConnection msk_vpc_connection = 1;
  BaseResp base_resp = 2;
}

message DeleteMSKVPCConnectionRequest {
  string msk_vpc_connection_arn = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
  string kubernetes = 4;
}

message DeleteMSKVPCConnectionResponse {
  BaseResp base_resp = 1;
}

message GetMSKVPCConnectionRequest {
  string msk_vpc_connection_arn = 1;
  uint64 project_id = 2;
  string cluster_id = 3;
  string kubernetes = 4;
}

message GetMSKVPCConnectionResponse {
  MSKVpcConnection msk_vpc_connection = 1;
  BaseResp base_resp = 2;
}
