syntax = "proto3";

package agentpb;

import "google/protobuf/duration.proto";
// Go Modules now includes the version in the filepath for packages within GOPATH/pkg/mode
// Therefore unless we want to hardcode a version here like
// github.com/gogo/protobuf@v1.3.0/gogoproto/gogo.proto then the only other choice is to
// have a more relative import and pass the right import path to protoc. I don't like it
// but its necessary.
import "gogoproto/gogo.proto";

option (gogoproto.goproto_unkeyed_all) = false;
option (gogoproto.goproto_unrecognized_all) = false;
option (gogoproto.goproto_getters_all) = false;
option (gogoproto.goproto_sizecache_all) = false;

// RaftIndex is used to track the index used while creating
// or modifying a given struct type.
message RaftIndex {
   uint64 CreateIndex = 1 [(gogoproto.moretags) = "bexpr:\"-\""];
   uint64 ModifyIndex = 2 [(gogoproto.moretags) = "bexpr:\"-\""];
}

// TargetDatacenter is intended to be used within other messages used for RPC routing
// amongst the various Consul datacenters
message TargetDatacenter {
   string Datacenter = 1;
}

message WriteRequest {
   option (gogoproto.goproto_getters) = true;
   
   // Token is the ACL token ID. If not provided, the 'anonymous'
   // token is assumed for backwards compatibility.
   string Token = 1;
}

// QueryOptions is used to specify various flags for read queries
message QueryOptions {
   // The autogenerated getters will implement half of the
   // structs.QueryOptionsCompat interface
   option (gogoproto.goproto_getters) = true;
   
   // Token is the ACL token ID. If not provided, the 'anonymous'
   // token is assumed for backwards compatibility.
   string Token = 1;

   // If set, wait until query exceeds given index. Must be provided
   // with MaxQueryTime.
   uint64 MinQueryIndex = 2;

   // Provided with MinQueryIndex to wait for change.
   google.protobuf.Duration MaxQueryTime = 3
      [(gogoproto.stdduration) = true, (gogoproto.nullable) = false];

   // If set, any follower can service the request. Results
   // may be arbitrarily stale.
   bool AllowStale = 4;

   // If set, the leader must verify leadership prior to
   // servicing the request. Prevents a stale read.
   bool RequireConsistent = 5;

   // If set, the local agent may respond with an arbitrarily stale locally
   // cached response. The semantics differ from AllowStale since the agent may
   // be entirely partitioned from the servers and still considered "healthy" by
   // operators. Stale responses from Servers are also arbitrarily stale, but can
   // provide additional bounds on the last contact time from the leader. It's
   // expected that servers that are partitioned are noticed and replaced in a
   // timely way by operators while the same may not be true for client agents.
   bool UseCache = 6;

   // If set and AllowStale is true, will try first a stale
   // read, and then will perform a consistent read if stale
   // read is older than value.
   google.protobuf.Duration MaxStaleDuration = 7
      [(gogoproto.stdduration) = true, (gogoproto.nullable) = false];

   // MaxAge limits how old a cached value will be returned if UseCache is true.
   // If there is a cached response that is older than the MaxAge, it is treated
   // as a cache miss and a new fetch invoked. If the fetch fails, the error is
   // returned. Clients that wish to allow for stale results on error can set
   // StaleIfError to a longer duration to change this behavior. It is ignored
   // if the endpoint supports background refresh caching. See
   // https://www.consul.io/api/index.html#agent-caching for more details.
   google.protobuf.Duration MaxAge = 8
      [(gogoproto.stdduration) = true, (gogoproto.nullable) = false];

   // MustRevalidate forces the agent to fetch a fresh version of a cached
   // resource or at least validate that the cached version is still fresh. It is
   // implied by either max-age=0 or must-revalidate Cache-Control headers. It
   // only makes sense when UseCache is true. We store it since MaxAge = 0 is the
   // default unset value.
   bool MustRevalidate = 9;

   // StaleIfError specifies how stale the client will accept a cached response
   // if the servers are unavailable to fetch a fresh one. Only makes sense when
   // UseCache is true and MaxAge is set to a lower, non-zero value. It is
   // ignored if the endpoint supports background refresh caching. See
   // https://www.consul.io/api/index.html#agent-caching for more details.
   google.protobuf.Duration StaleIfError = 10
      [(gogoproto.stdduration) = true, (gogoproto.nullable) = false];

   // Filter specifies the go-bexpr filter expression to be used for
   // filtering the data prior to returning a response
   string Filter = 11;
}

// QueryMeta allows a query response to include potentially
// useful metadata about a query
message QueryMeta  {
   // The auto-generated getters will implement half of the
   // structs.QueryMetaCompat interface
   option (gogoproto.goproto_getters) = true;
   
   // This is the index associated with the read
   uint64 Index = 1;

   // If AllowStale is used, this is time elapsed since
   // last contact between the follower and leader. This
   // can be used to gauge staleness.
   google.protobuf.Duration LastContact = 2
      [(gogoproto.stdduration) = true, (gogoproto.nullable) = false];

   // Used to indicate if there is a known leader node
   bool KnownLeader = 3;

   // Consistencylevel returns the consistency used to serve the query
   // Having `discovery_max_stale` on the agent can affect whether
   // the request was served by a leader.
   string ConsistencyLevel = 4;
}
