syntax = "proto3";

package global.nextgen.v1;

import "global/common/v1/service_plan.proto";
import "google/api/field_behavior.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

service ReservedCapacityTemplateService {
  rpc CreateReservedCapacityTemplate(CreateReservedCapacityTemplateRequest) returns (ReservedCapacityTemplate) {}
  rpc GetReservedCapacityTemplate(GetReservedCapacityTemplateRequest) returns (ReservedCapacityTemplate) {}
  rpc ListReservedCapacityTemplates(ListReservedCapacityTemplatesRequest) returns (ListReservedCapacityTemplatesResponse) {}
  rpc UpdateReservedCapacityTemplateStatus(UpdateReservedCapacityTemplateStatusRequest) returns (ReservedCapacityTemplate) {}
  rpc DeleteReservedCapacityTemplate(DeleteReservedCapacityTemplateRequest) returns (google.protobuf.Empty) {}
}

message CreateReservedCapacityTemplateRequest {
  ReservedCapacityTemplate reserved_capacity_template = 1 [(google.api.field_behavior) = REQUIRED];
}

message GetReservedCapacityTemplateRequest {
  uint64 capacity_template_id = 1 [(google.api.field_behavior) = REQUIRED];
}

message ListReservedCapacityTemplatesRequest {
  uint64 organization_id = 1 [(google.api.field_behavior) = OPTIONAL];
  ReservedCapacityTemplate.WorkloadType workload_type = 2 [(google.api.field_behavior) = OPTIONAL];
  int64 qps = 3 [(google.api.field_behavior) = OPTIONAL];
  int64 data_size_gib = 4 [(google.api.field_behavior) = OPTIONAL];
  int64 p99_response_latency = 5 [(google.api.field_behavior) = OPTIONAL];
  ReservedCapacityTemplate.Status status = 6 [(google.api.field_behavior) = OPTIONAL];
  ReservedCapacityTemplate.Scope scope = 7 [(google.api.field_behavior) = OPTIONAL];
  common.v1.ServicePlan service_plan = 8 [(google.api.field_behavior) = OPTIONAL];
  uint32 page_size = 100 [(google.api.field_behavior) = OPTIONAL];
  uint32 page = 101 [(google.api.field_behavior) = OPTIONAL];
}

message ListReservedCapacityTemplatesResponse {
  repeated ReservedCapacityTemplate reserved_capacity_templates = 1;
  uint32 total = 2;
}

message UpdateReservedCapacityTemplateStatusRequest {
  uint64 capacity_template_id = 1 [(google.api.field_behavior) = REQUIRED];
  ReservedCapacityTemplate.Status status = 2 [(google.api.field_behavior) = REQUIRED];
}

message DeleteReservedCapacityTemplateRequest {
  uint64 capacity_template_id = 1 [(google.api.field_behavior) = REQUIRED];
}

message ReservedCapacityTemplate {
  uint64 id = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  string template_code = 2 [(google.api.field_behavior) = OPTIONAL];
  string description = 3 [(google.api.field_behavior) = OPTIONAL];
  Scope scope = 4 [(google.api.field_behavior) = REQUIRED];
  uint64 organization_id = 5 [(google.api.field_behavior) = OPTIONAL];
  Status status = 6 [(google.api.field_behavior) = REQUIRED];
  int64 purchased_vcpu = 7 [(google.api.field_behavior) = REQUIRED];
  Workload workload = 8 [(google.api.field_behavior) = REQUIRED];
  FixedTopology fixed_topology = 9 [(google.api.field_behavior) = REQUIRED];
  string topology_summary = 10 [(google.api.field_behavior) = OPTIONAL];
  google.protobuf.Timestamp create_time = 100 [(google.api.field_behavior) = OUTPUT_ONLY];
  google.protobuf.Timestamp update_time = 101 [(google.api.field_behavior) = OUTPUT_ONLY];
  google.protobuf.Timestamp delete_time = 102 [(google.api.field_behavior) = OUTPUT_ONLY];

  message Workload {
    WorkloadType workload_type = 1 [(google.api.field_behavior) = REQUIRED];
    int64 qps_min = 2 [(google.api.field_behavior) = OPTIONAL];
    int64 qps_max = 3 [(google.api.field_behavior) = OPTIONAL];
    int64 data_size_gib_min = 4 [(google.api.field_behavior) = OPTIONAL];
    int64 data_size_gib_max = 5 [(google.api.field_behavior) = OPTIONAL];
    int64 p99_response_latency_min = 6 [(google.api.field_behavior) = OPTIONAL];
    int64 p99_response_latency_max = 7 [(google.api.field_behavior) = OPTIONAL];
  }

  enum Scope {
    SCOPE_UNSPECIFIED = 0;
    DEFAULT = 1;
    ORG_PRIVATE = 2;
  }

  enum Status {
    STATUS_UNSPECIFIED = 0;
    ACTIVE = 1;
    DEPRECATED = 2;
  }

  enum WorkloadType {
    WORKLOAD_TYPE_UNSPECIFIED = 0;
    READ = 1;
    WRITE = 2;
    MIXED = 3;
  }
}

message FixedTopology {
  repeated ComponentTopology components = 1 [(google.api.field_behavior) = REQUIRED];
}

message ComponentTopology {
  ComponentType component_type = 1 [(google.api.field_behavior) = REQUIRED];
  NodeQuota node_quota = 2 [(google.api.field_behavior) = REQUIRED];
  repeated StorageSpec storages = 3 [(google.api.field_behavior) = OPTIONAL];
}

message NodeQuota {
  NodeSpec node_spec = 1 [(google.api.field_behavior) = REQUIRED];
  uint32 node_count = 2 [(google.api.field_behavior) = REQUIRED];
}

message NodeSpec {
  uint32 cpu = 1 [(google.api.field_behavior) = REQUIRED];
  uint32 memory_gi = 2 [(google.api.field_behavior) = REQUIRED];
}

message StorageSpec {
  StorageName name = 1 [(google.api.field_behavior) = REQUIRED];
  string type = 2 [(google.api.field_behavior) = OPTIONAL];
  uint32 size_gi = 3 [(google.api.field_behavior) = REQUIRED];
  uint32 iops = 4 [(google.api.field_behavior) = OPTIONAL];
  uint32 throughput_mbs = 5 [(google.api.field_behavior) = OPTIONAL];

  enum StorageName {
    STORAGE_NAME_UNSPECIFIED = 0;
    DATA = 1;
    RAFTLOG = 2;
    SLOWLOG = 3;
  }
}

enum ComponentType {
  COMPONENT_TYPE_UNSPECIFIED = 0;
  TIDB = 1;
  TIKV = 2;
  PD = 4;
  TIPROXY = 5;
  TIDB_WORKER = 6;
  TIKV_WORKER = 7;
  COPROCESSOR_WORKER = 8;
  TIFLASH_WRITE = 9;
  TIFLASH_COMPUTE = 10;
  PD_TSO = 11;
  PD_SCHEDULING = 12;
  SCHEMA_MANAGER = 13;
}
