// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

syntax = "proto3";

// This package contains types used by the Raft storage backend that lives in
// the internal/storage/raft Go package.
package hashicorp.consul.internal.storage.raft;

import "annotations/ratelimit/ratelimit.proto";
import "google/protobuf/empty.proto";
import "pbresource/resource.proto";

// Forwarding service is used for forwarding write and consistent read
// operations to the Raft leader. It is served on Consul's multiplexed
// server port, which is the same port used for regular Raft traffic.
service ForwardingService {
  // Write handles a forwarded write operation.
  rpc Write(WriteRequest) returns (WriteResponse) {
    option (hashicorp.consul.internal.ratelimit.spec) = {
      operation_type: OPERATION_TYPE_EXEMPT,
      operation_category: OPERATION_CATEGORY_RESOURCE
    };
  }

  // Delete handles a forwarded delete operation.
  rpc Delete(DeleteRequest) returns (google.protobuf.Empty) {
    option (hashicorp.consul.internal.ratelimit.spec) = {
      operation_type: OPERATION_TYPE_EXEMPT,
      operation_category: OPERATION_CATEGORY_RESOURCE
    };
  }

  // Read handles a forwarded read operation.
  rpc Read(ReadRequest) returns (ReadResponse) {
    option (hashicorp.consul.internal.ratelimit.spec) = {
      operation_type: OPERATION_TYPE_EXEMPT,
      operation_category: OPERATION_CATEGORY_RESOURCE
    };
  }

  // List handles a forwarded list operation.
  rpc List(ListRequest) returns (ListResponse) {
    option (hashicorp.consul.internal.ratelimit.spec) = {
      operation_type: OPERATION_TYPE_EXEMPT,
      operation_category: OPERATION_CATEGORY_RESOURCE
    };
  }
}

// LogType describes the type of operation being written to the Raft log.
enum LogType {
  LOG_TYPE_UNSPECIFIED = 0;
  LOG_TYPE_WRITE = 1;
  LOG_TYPE_DELETE = 2;
}

// Log is protobuf-encoded and written to the Raft log.
message Log {
  LogType type = 1;

  oneof request {
    WriteRequest write = 2;
    DeleteRequest delete = 3;
  }
}

// LogResponse contains the FSM's response to applying a log.
message LogResponse {
  oneof response {
    WriteResponse write = 1;
    google.protobuf.Empty delete = 2;
  }
}

// WriteRequest contains the parameters for a write operation.
message WriteRequest {
  hashicorp.consul.resource.Resource resource = 1;
}

// WriteResponse contains the results of a write operation.
message WriteResponse {
  hashicorp.consul.resource.Resource resource = 1;
}

// DeleteRequest contains the parameters for a write operation.
message DeleteRequest {
  hashicorp.consul.resource.ID id = 1;
  string version = 2;
}

// ReadRequest contains the parameters for a consistent read operation.
message ReadRequest {
  hashicorp.consul.resource.ID id = 1;
}

// ReadResponse contains the results of a consistent read operation.
message ReadResponse {
  hashicorp.consul.resource.Resource resource = 1;
}

// ListRequest contains the parameters for a consistent list operation.
message ListRequest {
  hashicorp.consul.resource.Type type = 1;
  hashicorp.consul.resource.Tenancy tenancy = 2;
  string name_prefix = 3;
}

// ListResponse contains the results of a consistent list operation.
message ListResponse {
  repeated hashicorp.consul.resource.Resource resources = 1;
}

// GroupVersionMismatchErrorDetails contains the error details that will be
// returned when the leader encounters a storage.GroupVersionMismatchError.
message GroupVersionMismatchErrorDetails {
  hashicorp.consul.resource.Type requested_type = 1;
  hashicorp.consul.resource.Resource stored = 2;
}
