syntax = "proto3";

package EventStore.Client.Messages;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

message ReadEventCompleted {

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

	ReadEventResult result = 1;
	ResolvedIndexedEvent event = 2;

	string error = 3;
}

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

message ReadStreamEventsCompleted {

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

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

	string error = 7;
}

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

message ReadAllEventsCompleted {

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

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

	ReadAllResult result = 6;
	string error = 7;
}

message Filter{

	enum FilterContext {
        StreamId = 0;
		EventType = 1;

    }

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

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

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

message FilteredReadAllEventsCompleted {

    enum FilteredReadAllResult {
        Success = 0;
        NotModified = 1;
        Error = 2;
        AccessDenied = 3;
    }
    
    int64 commit_position = 1;
    int64 prepare_position = 2;
    repeated ResolvedEvent events = 3;
    int64 next_commit_position = 4;
    int64 next_prepare_position = 5;
    bool is_end_of_stream = 6;

    FilteredReadAllResult result = 7;
    string error = 8;
}

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

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

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

message UpdatePersistentSubscriptionCompleted {
	enum UpdatePersistentSubscriptionResult {
		Success = 0;
		DoesNotExist = 1;
		Fail = 2;
		AccessDenied=3;
	}
	UpdatePersistentSubscriptionResult result = 1;
	string reason = 2;
}

message CreatePersistentSubscriptionCompleted {
	enum CreatePersistentSubscriptionResult {
		Success = 0;
		AlreadyExists = 1;
		Fail = 2;
		AccessDenied=3;
	}
	CreatePersistentSubscriptionResult result = 1;
	string reason = 2;
}

message DeletePersistentSubscriptionCompleted {
	enum DeletePersistentSubscriptionResult {
		Success = 0;
		DoesNotExist = 1;
		Fail = 2;
		AccessDenied = 3;
	}
	DeletePersistentSubscriptionResult result = 1;
	string reason = 2;
}

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

}

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

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

	string subscription_id = 1;
	repeated bytes processed_event_ids = 2;
	string message = 3;
	NakAction action = 4;
}

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

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

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

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

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

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

message StreamEventAppeared {
	ResolvedEvent event = 1;
}

message UnsubscribeFromStream {
}

message SubscriptionDropped {

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

message NotHandled {
	
	enum NotHandledReason {
		NotReady = 0;
		TooBusy = 1;
		NotLeader = 2;
		IsReadOnly = 3;
	}
	
	NotHandledReason reason = 1;
	bytes additional_info = 2;

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

message ScavengeDatabase {
}

message ScavengeDatabaseResponse {
	
	enum ScavengeResult {
		Started = 0;
		InProgress = 1;
		Unauthorized = 2;
	}
	
	ScavengeResult result = 1;
	string scavengeId = 2;
	
}

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

message ClientIdentified {
}
