syntax = "proto3";

package kvrpc;

// Raw (Eventual Consistency) Operations
service KvRaw {
  rpc RawPut(RawPutRequest) returns (RawPutResponse);
  rpc RawGet(RawGetRequest) returns (RawGetResponse);
  rpc RawScan(RawScanRequest) returns (RawScanResponse);
  rpc RawDelete(RawDeleteRequest) returns (RawDeleteResponse);
}

message RawPutRequest {
  bytes key = 1;
  bytes value = 2;
  string namespace = 3;
}

message RawPutResponse {
  bool success = 1;
}

message RawGetRequest {
  bytes key = 1;
  string namespace = 2;
}

message RawGetResponse {
  bool found = 1;
  bytes value = 2;
}

// Raw scan request (eventual consistency)
message RawScanRequest {
  bytes start_key = 1;    // inclusive
  bytes end_key = 2;      // exclusive (empty = no upper bound)
  uint32 limit = 3;       // max entries to return (0 = default 100)
  string namespace = 4;
}

// Raw scan response
message RawScanResponse {
  repeated bytes keys = 1;
  repeated bytes values = 2;
  bool has_more = 3;      // true if more entries exist
  bytes next_key = 4;     // next start_key for pagination
}

message RawDeleteRequest {
  bytes key = 1;
  string namespace = 2;
}

message RawDeleteResponse {
  bool success = 1;
  bool existed = 2;       // true if key existed before deletion
}

// CAS (Strong Consistency / Optimistic) Operations
service KvCas {
  rpc CompareAndSwap(CasRequest) returns (CasResponse);
  rpc Get(GetRequest) returns (GetResponse);
  rpc Scan(ScanRequest) returns (ScanResponse);
  rpc Delete(DeleteRequest) returns (DeleteResponse);
}

message CasRequest {
  bytes key = 1;
  bytes value = 2;
  uint64 expected_version = 3; // 0 implies "create if not exists"
  string namespace = 4;
}

message CasResponse {
  bool success = 1;
  uint64 current_version = 2; // Returns current version on failure (for retry)
  uint64 new_version = 3;     // Returns assigned version on success
}

message GetRequest {
  bytes key = 1;
  string namespace = 2;
}

message GetResponse {
  bool found = 1;
  bytes value = 2;
  uint64 version = 3;
}

// CAS scan request (strong consistency)
message ScanRequest {
  bytes start_key = 1;    // inclusive
  bytes end_key = 2;      // exclusive (empty = no upper bound)
  uint32 limit = 3;       // max entries to return (0 = default 100)
  string namespace = 4;
}

// Key-value with version for CAS scan
message VersionedKv {
  bytes key = 1;
  bytes value = 2;
  uint64 version = 3;
}

// CAS scan response
message ScanResponse {
  repeated VersionedKv entries = 1;
  bool has_more = 2;      // true if more entries exist
  bytes next_key = 3;     // next start_key for pagination
}

message DeleteRequest {
  bytes key = 1;
  uint64 expected_version = 2; // 0 implies "delete if exists" (no version check)
  string namespace = 3;
}

message DeleteResponse {
  bool success = 1;
  uint64 current_version = 2; // Returns current version on failure (for retry)
  bool existed = 3;           // true if key existed before deletion
}
