enum OperationResult
{
	success = 0;
	prepare_timeout = 1;
	commit_timeout = 2;
	forward_timeout = 3;
	wrong_expected_version = 4;
	stream_deleted = 5;
	invalid_transaction = 6;
	access_denied = 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 {
	required EventRecord event = 1;
	optional EventRecord link = 2;
}

message ResolvedEvent {
	required 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_master = 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_master = 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;
}

message TransactionStart {
	required string event_stream_id = 1;
	required int64 expected_version = 2;
	required bool require_master = 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_master = 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_master = 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_master = 4;
}

message ReadEventCompleted {

	enum ReadEventResult {
		success = 0;
		not_found = 1;
		no_stream = 2;
		stream_deleted = 3;
		error = 4;
		access_denied = 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_master = 5;
}

message ReadStreamEventsBackward {
	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_master = 5;
}

message ReadStreamEventsCompleted {

	enum ReadStreamResult {
		success = 0;
		no_stream = 1;
		stream_deleted = 2;
		not_modified = 3;
		error = 4;
		access_denied = 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_master = 5;
}

message ReadAllEventsCompleted {

	enum ReadAllResult {
		success = 0;
		not_modified = 1;
		error = 2;
		access_denied = 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 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;
		does_not_exist = 1;
		fail = 2;
		access_denied=3;
	}
	required UpdatePersistentSubscriptionResult result = 1 [default = success];
	optional string reason = 2;
}

message CreatePersistentSubscriptionCompleted {
	enum CreatePersistentSubscriptionResult {
		success = 0;
		already_exists = 1;
		fail = 2;
		access_denied=3;
	}
	required CreatePersistentSubscriptionResult result = 1 [default = success];
	optional string reason = 2;
}

message DeletePersistentSubscriptionCompleted {
	enum DeletePersistentSubscriptionResult {
		success = 0;
		does_not_exist = 1;
		fail = 2;
		access_denied = 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 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;
		access_denied = 1;
		not_found=2;
		persistent_subscription_deleted=3;
		subscriber_max_count_reached=4;
	}
	
	optional SubscriptionDropReason reason = 1 [default = unsubscribed];
}

message NotHandled {
	
	enum NotHandledReason {
		not_ready = 0;
		too_busy = 1;
		not_master = 2;
	}
	
	required NotHandledReason reason = 1;
	optional bytes additional_info = 2;

	message MasterInfo {
		required string external_tcp_address = 1;
		required int32 external_tcp_port = 2;
		required string external_http_address = 3;
		required int32 external_http_port = 4;
		optional string external_secure_tcp_address = 5;
		optional int32 external_secure_tcp_port = 6;
	}
}

message ScavengeDatabase {
}

message ScavengeDatabaseCompleted {
	
	enum ScavengeResult {
		success = 0;
		in_progress = 1;
		failed = 2;
	}
	
	required ScavengeResult result = 1;
	optional string error = 2;
	required int32 total_time_ms = 3;
	required int64 total_space_saved = 4;
}

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

message ClientIdentified {
}
