syntax = "proto2";

package EventStore.Client.Messages;

enum OperationResult
{
	Success = 0;
	PrepareTimeout = 1;
	CommitTimeout = 2;
	ForwardTimeout = 3;
	WrongExpectedVersion = 4;
	StreamDeleted = 5;
	InvalidTransaction = 6;
	AccessDenied = 7;
}

message NewEvent {
	required bytes event_id = 1;
	required string event_type = 2;
	required int32 data_content_type = 3;
	required int32 metadata_content_type = 4;
	required bytes data = 5;
	optional bytes metadata = 6;
}

message EventRecord {
	required string event_stream_id = 1;
	required int64 event_number = 2;
	required bytes event_id = 3;
	required string event_type = 4;
	required int32 data_content_type = 5;
	required int32 metadata_content_type = 6;
	required bytes data = 7;
	optional bytes metadata = 8;
	optional int64 created = 9;
	optional int64 created_epoch = 10;
}

message ResolvedIndexedEvent {
	optional EventRecord event = 1;
	optional EventRecord link = 2;
}

message ResolvedEvent {
	optional EventRecord event = 1;
	optional EventRecord link = 2;
	required int64 commit_position = 3;
	required int64 prepare_position = 4;
}

message WriteEvents {
	required string event_stream_id = 1;
	required int64 expected_version = 2;
	repeated NewEvent events = 3;
	required bool require_leader = 4;
}

message WriteEventsCompleted {
	required OperationResult result = 1;
	optional string message = 2;
	required int64 first_event_number = 3;
	required int64 last_event_number = 4;
	optional int64 prepare_position = 5;
	optional int64 commit_position = 6;
	optional int64 current_version  = 7;
}

message DeleteStream {
	required string event_stream_id = 1;
	required int64 expected_version = 2;
	required bool require_leader = 3;
	optional bool hard_delete = 4;
}

message DeleteStreamCompleted {
	required OperationResult result = 1;
	optional string message = 2;
	optional int64 prepare_position = 3;
	optional int64 commit_position = 4;
	optional int64 current_version = 5;
}

message TransactionStart {
	required string event_stream_id = 1;
	required int64 expected_version = 2;
	required bool require_leader = 3;
}

message TransactionStartCompleted {
	required int64 transaction_id = 1;
	required OperationResult result = 2;
	optional string message = 3;
}

message TransactionWrite {
	required int64 transaction_id = 1;
	repeated NewEvent events = 2;
	required bool require_leader = 3;
}

message TransactionWriteCompleted {
	required int64 transaction_id = 1;
	required OperationResult result = 2;
	optional string message = 3;
}

message TransactionCommit {
	required int64 transaction_id = 1;
	required bool require_leader = 2;
}

message TransactionCommitCompleted {
	required int64 transaction_id = 1;
	required OperationResult result = 2;
	optional string message = 3;
	required int64 first_event_number = 4;
	required int64 last_event_number = 5;
	optional int64 prepare_position = 6;
	optional int64 commit_position = 7;
}

message ReadEvent {
	required string event_stream_id = 1;
	required int64 event_number = 2;
	required bool resolve_link_tos = 3;
	required bool require_leader = 4;
}

message ReadEventCompleted {

	enum ReadEventResult {
		Success = 0;
		NotFound = 1;
		NoStream = 2;
		StreamDeleted = 3;
		Error = 4;
		AccessDenied = 5;
	}

	required ReadEventResult result = 1;
	required ResolvedIndexedEvent event = 2;

	optional string error = 3;
}

message ReadStreamEvents {
	required string event_stream_id = 1;
	required int64 from_event_number = 2;
	required int32 max_count = 3;
	required bool resolve_link_tos = 4;
	required bool require_leader = 5;
}

message ReadStreamEventsCompleted {

	enum ReadStreamResult {
		Success = 0;
		NoStream = 1;
		StreamDeleted = 2;
		NotModified = 3;
		Error = 4;
		AccessDenied = 5;
	}

	repeated ResolvedIndexedEvent events = 1;
	required ReadStreamResult result = 2;
	required int64 next_event_number = 3;
	required int64 last_event_number = 4;
	required bool is_end_of_stream = 5;
	required int64 last_commit_position = 6;

	optional string error = 7;
}

message ReadAllEvents {
	required int64 commit_position = 1;
	required int64 prepare_position = 2;
	required int32 max_count = 3;
	required bool resolve_link_tos = 4;
	required bool require_leader = 5;
}

message ReadAllEventsCompleted {

	enum ReadAllResult {
		Success = 0;
		NotModified = 1;
		Error = 2;
		AccessDenied = 3;
	}

	required int64 commit_position = 1;
	required int64 prepare_position = 2;
	repeated ResolvedEvent events = 3;
	required int64 next_commit_position = 4;
	required int64 next_prepare_position = 5;

	optional ReadAllResult result = 6 [default = Success];
	optional string error = 7;
}

message Filter{

	enum FilterContext {
        StreamId = 0;
		EventType = 1;

    }

	enum FilterType {
        Regex = 0;
		Prefix = 1;
    }

    required FilterContext context = 1;
    required FilterType type = 2;
    repeated string data = 3;
}

message FilteredReadAllEvents {
    required int64 commit_position = 1;
    required int64 prepare_position = 2;
    required int32 max_count = 3;
    optional int32 max_search_window = 4;
    required bool resolve_link_tos = 5;
    required bool require_leader = 6;
    required Filter filter = 7;
}

message FilteredReadAllEventsCompleted {

    enum FilteredReadAllResult {
        Success = 0;
        NotModified = 1;
        Error = 2;
        AccessDenied = 3;
    }

    required int64 commit_position = 1;
    required int64 prepare_position = 2;
    repeated ResolvedEvent events = 3;
    required int64 next_commit_position = 4;
    required int64 next_prepare_position = 5;
    required bool is_end_of_stream = 6;

    optional FilteredReadAllResult result = 7 [default = Success];
    optional string error = 8;
}

message CreatePersistentSubscription {
	required string subscription_group_name = 1;
	required string event_stream_id = 2;
	required bool resolve_link_tos = 3;
	required int64 start_from = 4;
	required int32 message_timeout_milliseconds = 5;
	required bool record_statistics = 6;
	required int32 live_buffer_size = 7;
	required int32 read_batch_size = 8;
	required int32 buffer_size = 9;
	required int32 max_retry_count = 10;
	required bool prefer_round_robin = 11;
	required int32 checkpoint_after_time = 12;
	required int32 checkpoint_max_count = 13;
	required int32 checkpoint_min_count = 14;
	required int32 subscriber_max_count = 15;
	optional string named_consumer_strategy = 16;
}

message DeletePersistentSubscription {
	required string subscription_group_name = 1;
	required string event_stream_id = 2;
}

message UpdatePersistentSubscription {
	required string subscription_group_name = 1;
	required string event_stream_id = 2;
	required bool resolve_link_tos = 3;
	required int64 start_from = 4;
	required int32 message_timeout_milliseconds = 5;
	required bool record_statistics = 6;
	required int32 live_buffer_size = 7;
	required int32 read_batch_size = 8;
	required int32 buffer_size = 9;
	required int32 max_retry_count = 10;
	required bool prefer_round_robin = 11;
	required int32 checkpoint_after_time = 12;
	required int32 checkpoint_max_count = 13;
	required int32 checkpoint_min_count = 14;
	required int32 subscriber_max_count = 15;
	optional string named_consumer_strategy = 16;
}

message UpdatePersistentSubscriptionCompleted {
	enum UpdatePersistentSubscriptionResult {
		Success = 0;
		DoesNotExist = 1;
		Fail = 2;
		AccessDenied=3;
	}
	required UpdatePersistentSubscriptionResult result = 1 [default = Success];
	optional string reason = 2;
}

message CreatePersistentSubscriptionCompleted {
	enum CreatePersistentSubscriptionResult {
		Success = 0;
		AlreadyExists = 1;
		Fail = 2;
		AccessDenied=3;
	}
	required CreatePersistentSubscriptionResult result = 1 [default = Success];
	optional string reason = 2;
}

message DeletePersistentSubscriptionCompleted {
	enum DeletePersistentSubscriptionResult {
		Success = 0;
		DoesNotExist = 1;
		Fail = 2;
		AccessDenied = 3;
	}
	required DeletePersistentSubscriptionResult result = 1 [default = Success];
	optional string reason = 2;
}

message ConnectToPersistentSubscription {
	required string subscription_id = 1;
	required string event_stream_id = 2;
	required int32 allowed_in_flight_messages = 3;

}

message PersistentSubscriptionAckEvents {
	required string subscription_id = 1;
	repeated bytes processed_event_ids = 2;
}

message PersistentSubscriptionNakEvents {
	enum NakAction {
		Unknown = 0;
		Park = 1;
		Retry = 2;
		Skip = 3;
		Stop = 4;
	}

	required string subscription_id = 1;
	repeated bytes processed_event_ids = 2;
	optional string message = 3;
	required NakAction action = 4 [default = Unknown];
}

message PersistentSubscriptionConfirmation {
	required int64 last_commit_position = 1;
	required string subscription_id = 2;
	optional int64 last_event_number = 3;
}

message PersistentSubscriptionStreamEventAppeared {
	required ResolvedIndexedEvent event = 1;
	optional int32 retryCount = 2;
}

message SubscribeToStream {
	required string event_stream_id = 1;
	required bool resolve_link_tos = 2;
}

message FilteredSubscribeToStream {
	required string event_stream_id = 1;
	required bool resolve_link_tos = 2;
	required Filter filter = 3;
	required int32 checkpoint_interval = 4;
}

message CheckpointReached {
	required int64 commit_position = 1;
	required int64 prepare_position = 2;
}

message SubscriptionConfirmation {
	required int64 last_commit_position = 1;
	optional int64 last_event_number = 2;
}

message StreamEventAppeared {
	required ResolvedEvent event = 1;
}

message UnsubscribeFromStream {
}

message SubscriptionDropped {

	enum SubscriptionDropReason {
		Unsubscribed = 0;
		AccessDenied = 1;
		NotFound=2;
		PersistentSubscriptionDeleted=3;
		SubscriberMaxCountReached=4;
	}

	optional SubscriptionDropReason reason = 1 [default = Unsubscribed];
}

message NotHandled {

	enum NotHandledReason {
		NotReady = 0;
		TooBusy = 1;
		NotLeader = 2;
		IsReadOnly = 3;
	}

	required NotHandledReason reason = 1;
	optional bytes additional_info = 2;

	message LeaderInfo {
		optional string external_tcp_address = 1;
		optional int32 external_tcp_port = 2;
		required string http_address = 3;
		required int32 http_port = 4;
		optional string external_secure_tcp_address = 5;
		optional int32 external_secure_tcp_port = 6;
	}
}

message ScavengeDatabase {
}

message ScavengeDatabaseResponse {

	enum ScavengeResult {
		Started = 0;
		InProgress = 1;
		Unauthorized = 2;
	}

	required ScavengeResult result = 1;
	optional string scavengeId = 2;

}

message IdentifyClient {
	required int32 version = 1;
	optional string connection_name = 2;
}

message ClientIdentified {
}
