// Copyright 2022 Lightbend Inc.

syntax = "proto3";

package kalix.backoffice;

import "google/protobuf/any.proto";
import "google/protobuf/descriptor.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";
import "kalix/protocol/discovery.proto";

option go_package = "github.com/lightbend/kalix-go-sdk/kalix/backoffice;backoffice";
option java_package = "kalix.backoffice";

// The backoffice service allows accessing backoffice functions of the proxy.
service BackofficeService {
  // Get the discovery spec that was discovered in this service
  rpc GetDiscoverySpec(google.protobuf.Empty) returns (kalix.protocol.Spec);
  // List the components served by this service.
  rpc ListComponents(ListComponentsRequest) returns (ListComponentsResponse);
  // List the entity ids for a given entity type.
  rpc ListEntityIds(ListEntityIdsRequest) returns (ListEntityIdsResponse);
  // List the events for a given event sourced entity.
  rpc ListEventSourcedEntityEvents(ListEventSourcedEntityEventsRequest) returns (ListEventSourcedEntityEventsResponse);
  // Get the state for a given entity
  rpc GetEntityState(GetEntityStateRequest) returns (EntityState);

  // TODO: When making public for users we should add something to list projectionIds and maybe we
  // should have some more public representation of projectionId. Maybe the individual projection
  // instances (slices) shouldn't be exposed. Maybe use the component name of a View or Action.

  rpc PauseProjection(ProjectionId) returns (google.protobuf.Empty);
  rpc ResumeProjection(ProjectionId) returns (google.protobuf.Empty);
  rpc GetProjectionStatus(ProjectionId) returns (ProjectionStatus);
  rpc UpdateProjectionOffset(UpdateProjectionOffsetReq) returns (google.protobuf.Empty);
  rpc ClearProjectionOffset(ProjectionId) returns (google.protobuf.Empty);
  rpc ListViews(ListViewsRequest) returns (ListViewsResponse);
  rpc DropView(DropViewRequest) returns (DropViewResponse);
}

message View {
  string name = 1;
  google.protobuf.Timestamp last_updated = 2;
  // warning: when false, *this* node thinks this view is no longer active.
  // during a rolling update, other nodes might still be actively using
  // this index.
  bool active = 3;
}

message ListViewsRequest {
  // could add a token later
}

message ListViewsResponse {
  repeated View views = 1;
  // could add a next_token later
}

message DropViewRequest {
  string name = 1;
  // when the view is currently in use by this node, we only allow deleting it when this flag is true.
  bool force = 2;
}

message DropViewResponse {}

message ListComponentsRequest {
  // The size of the pages to request.
  //
  // Defaults to 100. Must not be more than 100.
  int32 page_size = 1;
  // The token of the page to request.
  //
  // This is an opaque value that must be copied, unmodified, from the the next_page_token field of a returned
  // response. The request that produced this token must be identical to this request, aside from the token itself.
  string page_token = 2;
}

message ListComponentsResponse {
  // The components served by this service.
  repeated kalix.protocol.Component components = 1;
  // The token for the next page.
  //
  // If there are more pages, this field will be non empty, and may be passed in the page_token field of the request
  // to retrieve the next page.
  string next_page_token = 2;
}

message ListEntityIdsRequest {
  // The name of the service for the entity.
  string service_name = 1;
  // The size of the pages to request.
  //
  // Defaults to 100. Must not be more than 100.
  int32 page_size = 2;
  // The token of the page to request.
  //
  // This is an opaque value that must be copied, unmodified, from the the next_page_token field of a returned
  // response. The request that produced this token must be identical to this request, aside from the token itself.
  string page_token = 3;
}

message ListEntityIdsResponse {
  // The entity ids for this entity.
  repeated string ids = 1;
  // The token for the next page.
  //
  // If there are more pages, this field will be non empty, and may be passed in the page_token field of the request
  // to retrieve the next page.
  string next_page_token = 2;
}

message ListEventSourcedEntityEventsRequest {
  // The name of the service for the entity.
  string service_name = 1;
  // The id of the entity to list the events of.
  string entity_id = 2;
  // Whether the state of the entity should be included with each event.
  bool include_state = 3;
  // The size of the pages to request.
  //
  // Defaults to 100. Must not be more than 100.
  int32 page_size = 4;
  // The token of the page to request.
  //
  // This is an opaque value that must be copied, unmodified, from the the next_page_token field of a returned
  // response. The request that produced this token must be identical to this request, aside from the token itself.
  string page_token = 5;
}

message ListEventSourcedEntityEventsResponse {
  // The events for this entity.
  repeated EventSourcedEntityEvent events = 1;
  // The token for the next page.
  //
  // If there are more pages, this field will be non empty, and may be passed in the page_token field of the request
  // to retrieve the next page.
  string next_page_token = 2;
}

message EventSourcedEntityEvent {
  // The name of the service that the entity is part of.
  string service_name = 1;
  // The id of the entity
  string entity_id = 2;
  // The 1 based sequence number for the event.
  int64 sequence = 3;
  // An opaque value that is used for ordering of events between different entity types.
  string offset = 4;
  // When the event was created.
  google.protobuf.Timestamp timestamp = 5;
  // The event payload
  google.protobuf.Any event = 6;
  // The state, only present if include_state was true in the request.
  google.protobuf.Any state = 7;
}

message GetEntityStateRequest {
  // The name of the service that the entity is part of.
  string service_name = 1;
  // The id of the entity.
  string entity_id = 2;
}

message EntityState {
  // The name of the service that the entity is part of.
  string service_name = 1;
  // The id of the entity.
  string entity_id = 2;
  // The state.
  google.protobuf.Any state = 3;
  // The sequence number of the entity, if the entity type supports sequence numbers.
  int64 sequence = 4;
}

message ProjectionStatus {
  bool paused = 1;
  string offset = 2;
}

message ProjectionId {
  string name = 1;
  string key = 2;
}

message UpdateProjectionOffsetReq {
  ProjectionId projection_id = 1;
  string offset = 2;
}
