syntax = "proto3";

package umadb;

// Event message
message EventProto {
  string event_type = 1;
  repeated string tags = 2;
  bytes data = 3;
  string uuid = 4;
}

// Sequenced Event message
message SequencedEventProto {
  uint64 position = 1;
  EventProto event = 2;
}

// Query Item message
message QueryItemProto {
  repeated string types = 1;
  repeated string tags = 2;
}

// Query message
message QueryProto {
  repeated QueryItemProto items = 1;
}

// Append Condition message
message AppendConditionProto {
  optional QueryProto fail_if_events_match = 1;
  optional uint64 after = 2;
}

// Read request message
message ReadRequestProto {
  optional QueryProto query = 1;
  optional uint64 start = 2;
  optional bool backwards = 3;
  optional uint32 limit = 4;
  optional bool subscribe = 5;
  optional uint32 batch_size = 6;
}

// Read response message
message ReadResponseProto {
  repeated SequencedEventProto events = 1;
  optional uint64 head = 2;
}

// Append request message
message AppendRequestProto {
  repeated EventProto events = 1;
  optional AppendConditionProto condition = 2;
}

// Append response message
message AppendResponseProto {
  uint64 position = 1;
}

// Head request message
message HeadRequestProto {
  // Empty request, no parameters needed
}

// Head response message
message HeadResponseProto {
  optional uint64 position = 1;
}

// Error response
message ErrorResponseProto {
  string message = 1;
  ErrorType error_type = 2;

  enum ErrorType {
    IO = 0;
    SERIALIZATION = 1;
    INTEGRITY = 2;
    CORRUPTION = 3;
    INTERNAL = 4;
  }
}

// UmaDB service
service UmaDBService {
  // Read events from the store
  rpc Read(ReadRequestProto) returns (stream ReadResponseProto);

  // Append events to the store
  rpc Append(AppendRequestProto) returns (AppendResponseProto);

  // Get the current head position of the event store
  rpc Head(HeadRequestProto) returns (HeadResponseProto);
}
