// 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.meta;

option go_package = "github.com/GreptimeTeam/greptime-proto/go/greptime/v1/meta";

import "greptime/v1/meta/common.proto";

service Store {
  // Range gets the keys in the range from the key-value store.
  rpc Range(RangeRequest) returns (RangeResponse);

  // Put puts the given key into the key-value store.
  rpc Put(PutRequest) returns (PutResponse);

  // BatchGet atomically get values by the given keys from the key-value store.
  rpc BatchGet(BatchGetRequest) returns (BatchGetResponse);

  // BatchPut atomically puts the given keys into the key-value store.
  rpc BatchPut(BatchPutRequest) returns (BatchPutResponse);

  // BatchDelete atomically deletes the given keys and its associating values
  // from the key-value store.
  rpc BatchDelete(BatchDeleteRequest) returns (BatchDeleteResponse);

  // CompareAndPut atomically puts the value to the given updated
  // value if the current value == the expected value.
  rpc CompareAndPut(CompareAndPutRequest) returns (CompareAndPutResponse);

  // DeleteRange deletes the given range from the key-value store.
  rpc DeleteRange(DeleteRangeRequest) returns (DeleteRangeResponse);
}

message RangeRequest {
  RequestHeader header = 1;

  // key is the first key for the range, If range_end is not given, the
  // request only looks up key.
  bytes key = 2;
  // range_end is the upper bound on the requested range [key, range_end).
  // If range_end is '\0', the range is all keys >= key.
  // If range_end is key plus one (e.g., "aa"+1 == "ab", "a\xff"+1 == "b"),
  // then the range request gets all keys prefixed with key.
  // If both key and range_end are '\0', then the range request returns all
  // keys.
  bytes range_end = 3;
  // limit is a limit on the number of keys returned for the request. When
  // limit is set to 0, it is treated as no limit.
  int64 limit = 4;
  // keys_only when set returns only the keys and not the values.
  bool keys_only = 5;
}

message RangeResponse {
  ResponseHeader header = 1;

  // kvs is the list of key-value pairs matched by the range request.
  repeated KeyValue kvs = 2;
  // more indicates if there are more keys to return in the requested range.
  bool more = 3;
}

message PutRequest {
  RequestHeader header = 1;

  // key is the key, in bytes, to put into the key-value store.
  bytes key = 2;
  // value is the value, in bytes, to associate with the key in the
  // key-value store.
  bytes value = 3;
  // If prev_kv is set, gets the previous key-value pair before changing it.
  // The previous key-value pair will be returned in the put response.
  bool prev_kv = 4;
}

message PutResponse {
  ResponseHeader header = 1;

  // If prev_kv is set in the request, the previous key-value pair will be
  // returned.
  KeyValue prev_kv = 2;
}

message BatchGetRequest {
  RequestHeader header = 1;

  repeated bytes keys = 2;
}

message BatchGetResponse {
  ResponseHeader header = 1;

  repeated KeyValue kvs = 2;
}

message BatchPutRequest {
  RequestHeader header = 1;

  repeated KeyValue kvs = 2;
  // If prev_kv is set, gets the previous key-value pairs before changing it.
  // The previous key-value pairs will be returned in the batch put response.
  bool prev_kv = 3;
}

message BatchPutResponse {
  ResponseHeader header = 1;

  // If prev_kv is set in the request, the previous key-value pairs will be
  // returned.
  repeated KeyValue prev_kvs = 2;
}

message BatchDeleteRequest {
  RequestHeader header = 1;

  repeated bytes keys = 2;
  // If prev_kv is set, gets the previous key-value pairs before deleting it.
  // The previous key-value pairs will be returned in the batch delete response.
  bool prev_kv = 3;
}

message BatchDeleteResponse {
  ResponseHeader header = 1;

  // If prev_kv is set in the request, the previous key-value pairs will be
  // returned.
  repeated KeyValue prev_kvs = 2;
}

message CompareAndPutRequest {
  RequestHeader header = 1;

  // key is the key, in bytes, to put into the key-value store.
  bytes key = 2;
  // expect is the previous value, in bytes
  bytes expect = 3;
  // value is the value, in bytes, to associate with the key in the
  // key-value store.
  bytes value = 4;
}

message CompareAndPutResponse {
  ResponseHeader header = 1;

  bool success = 2;
  KeyValue prev_kv = 3;
}

message DeleteRangeRequest {
  RequestHeader header = 1;

  // key is the first key to delete in the range.
  bytes key = 2;
  // range_end is the key following the last key to delete for the range
  // [key, range_end).
  // If range_end is not given, the range is defined to contain only the key
  // argument.
  // If range_end is one bit larger than the given key, then the range is all
  // the keys with the prefix (the given key).
  // If range_end is '\0', the range is all keys greater than or equal to the
  // key argument.
  bytes range_end = 3;
  // If prev_kv is set, gets the previous key-value pairs before deleting it.
  // The previous key-value pairs will be returned in the delete response.
  bool prev_kv = 4;
}

message DeleteRangeResponse {
  ResponseHeader header = 1;

  // deleted is the number of keys deleted by the delete range request.
  int64 deleted = 2;
  // If prev_kv is set in the request, the previous key-value pairs will be
  // returned.
  repeated KeyValue prev_kvs = 3;
}
