// Copyright 2023 Greptime Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package greptime.v1.region;

option java_package = "io.greptime.v1.region";
option java_outer_classname = "Server";
option go_package = "github.com/GreptimeTeam/greptime-proto/go/greptime/v1/region";

import "greptime/v1/common.proto";
import "greptime/v1/row.proto";
import "greptime/v1/ddl.proto";

service Region { rpc Handle(RegionRequest) returns (RegionResponse); }

message RegionRequestHeader {
  // Encoded trace_id & span_id, follow the w3c Trace Context
  // https://www.w3.org/TR/trace-context/#header-name
  map<string, string> tracing_context = 5;
  // DB Name of request, tracking only
  string dbname = 3;
  // The contextual information of the query
  QueryContext query_context = 6;
}

message RegionRequest {
  RegionRequestHeader header = 1;
  // query request is handled in flight services.
  oneof body {
    InsertRequests inserts = 3;
    DeleteRequests deletes = 4;
    CreateRequest create = 5;
    DropRequest drop = 6;
    OpenRequest open = 7;
    CloseRequest close = 8;
    AlterRequest alter = 9;
    FlushRequest flush = 10;
    CompactRequest compact = 11;
    TruncateRequest truncate = 12;
    CreateRequests creates = 13;
    DropRequests drops = 14;
    AlterRequests alters = 15;
    BulkInsertRequest bulk_insert = 16;
    SyncRequest sync = 17;
  }
}

message RegionResponse {
  ResponseHeader header = 1;
  uint64 affected_rows = 2;
  map<string, bytes> extensions = 3;
}

message InsertRequests { repeated InsertRequest requests = 1; }

message DeleteRequests { repeated DeleteRequest requests = 1; }

message InsertRequest {
  uint64 region_id = 1;
  Rows rows = 2;
}

message DeleteRequest {
  uint64 region_id = 1;
  Rows rows = 2;
}

message QueryRequest {
  RegionRequestHeader header = 1;
  uint64 region_id = 2;
  // substrait plan to query
  bytes plan = 3;
}

// Create a batch of regions at once, usually used to create multiple logical
// regions at once. Different engines can choose whether to support this
// request. Metric Engine needs it.
message CreateRequests { repeated CreateRequest requests = 1; }

message CreateRequest {
  uint64 region_id = 1;
  // Region engine name
  string engine = 2;
  // Columns in this region.
  repeated RegionColumnDef column_defs = 3;
  // Column Id of primary keys.
  repeated uint32 primary_key = 4;
  // Region storage path
  string path = 5;
  // Options of the created region.
  map<string, string> options = 6;
  // TODO: add partition def
}

// Same as CreateRequests, but for dropping regions.
message DropRequests { repeated DropRequest requests = 1; }

message DropRequest {
  uint64 region_id = 1;
  // Only used by Metric Engine, for fast path drop.
  // It only works for Metric Engine, and will be ignored by other engines.
  // If true, the Metric Engine will delete logical tables in memory, and drop the physical region eventually.
  bool fast_path = 2;
}

message OpenRequest {
  uint64 region_id = 1;
  // Region engine name
  string engine = 2;
  // Region storage path
  string path = 3;
  // Options of the opened region.
  map<string, string> options = 4;
}

message CloseRequest { uint64 region_id = 1; }

message AlterRequests { repeated AlterRequest requests = 1; }

message AlterRequest {
  uint64 region_id = 1;
  oneof kind {
    AddColumns add_columns = 2;
    DropColumns drop_columns = 3;
    ModifyColumnTypes modify_column_types = 5;
    SetTableOptions set_table_options = 6;
    UnsetTableOptions unset_table_options = 9;
    SetIndex set_index = 10;
    UnsetIndex unset_index = 11;
  }
  // The version of the schema before applying the alteration.
  uint64 schema_version = 4;
}

message AddColumns { repeated AddColumn add_columns = 1; }

message DropColumns { repeated DropColumn drop_columns = 1; }

message AddColumn {
  RegionColumnDef column_def = 1;
  AddColumnLocation location = 3;
}

message DropColumn { string name = 1; }

message FlushRequest { uint64 region_id = 1; }

/// Regular compaction
message Regular {}

/// Strictly-windowed compaction.
message StrictWindow {
  int64 window_seconds = 1;
}

message CompactRequest {
    uint64 region_id = 1;
    oneof options {
      Regular regular = 2;
      StrictWindow strict_window = 3;
    }
}

message TruncateRequest { uint64 region_id = 1; }

// The column definition of a region. Unlike the message `ColumnDef` in
// `ddl.proto` which is for clients outside GreptimeDB, this `RegionColumnDef`
// is for region requests use only. So it carries an extra field `column_id`
// that is known internally.
message RegionColumnDef {
  ColumnDef column_def = 1;
  uint32 column_id = 2;
}

// Request of bulk ingestion API.
message BulkInsertRequest {
  oneof body {
    ArrowIpc arrow_ipc = 1;
  }
}

message ArrowIpc {
  uint64 region_id = 1;
  bytes schema = 2;
  bytes data_header = 3;
  bytes payload = 4;
}

// Manifest info for mito engine.
message MitoManifestInfo {
  uint64 data_manifest_version = 1;
}

// Manifest info for metric engine.
message MetricManifestInfo {
  uint64 data_manifest_version = 1;
  uint64 metadata_manifest_version = 2;
}

// Sync request for region.
message SyncRequest {
  uint64 region_id = 1;
  oneof manifest_info {
    MitoManifestInfo mito_manifest_info = 2;
    MetricManifestInfo metric_manifest_info = 3;
  }
}
