syntax = "proto3";

package mpc.router.v1;

option java_package = "com.durian.tssparty.grpc";
option java_outer_classname = "MessageRouterProto";
option java_multiple_files = true;

// MessageRouter service handles MPC message routing
service MessageRouter {
  // RouteMessage routes a message from one party to others
  rpc RouteMessage(RouteMessageRequest) returns (RouteMessageResponse);

  // SubscribeMessages subscribes to messages for a party (streaming)
  rpc SubscribeMessages(SubscribeMessagesRequest) returns (stream MPCMessage);

  // GetPendingMessages retrieves pending messages (polling alternative)
  rpc GetPendingMessages(GetPendingMessagesRequest) returns (GetPendingMessagesResponse);

  // AcknowledgeMessage acknowledges receipt of a message
  rpc AcknowledgeMessage(AcknowledgeMessageRequest) returns (AcknowledgeMessageResponse);

  // RegisterParty registers a party with the message router
  rpc RegisterParty(RegisterPartyRequest) returns (RegisterPartyResponse);

  // Heartbeat sends a heartbeat to keep the party alive
  rpc Heartbeat(HeartbeatRequest) returns (HeartbeatResponse);

  // SubscribeSessionEvents subscribes to session lifecycle events
  rpc SubscribeSessionEvents(SubscribeSessionEventsRequest) returns (stream SessionEvent);

  // JoinSession joins a session (proxied to Session Coordinator)
  rpc JoinSession(JoinSessionRequest) returns (JoinSessionResponse);

  // MarkPartyReady marks a party as ready
  rpc MarkPartyReady(MarkPartyReadyRequest) returns (MarkPartyReadyResponse);

  // ReportCompletion reports protocol completion
  rpc ReportCompletion(ReportCompletionRequest) returns (ReportCompletionResponse);

  // GetSessionStatus gets session status
  rpc GetSessionStatus(GetSessionStatusRequest) returns (GetSessionStatusResponse);
}

message RouteMessageRequest {
  string session_id = 1;
  string from_party = 2;
  repeated string to_parties = 3;
  int32 round_number = 4;
  string message_type = 5;
  bytes payload = 6;
}

message RouteMessageResponse {
  bool success = 1;
  string message_id = 2;
}

message SubscribeMessagesRequest {
  string session_id = 1;
  string party_id = 2;
}

message MPCMessage {
  string message_id = 1;
  string session_id = 2;
  string from_party = 3;
  bool is_broadcast = 4;
  int32 round_number = 5;
  string message_type = 6;
  bytes payload = 7;
  int64 created_at = 8;
}

message GetPendingMessagesRequest {
  string session_id = 1;
  string party_id = 2;
  int64 after_timestamp = 3;
}

message GetPendingMessagesResponse {
  repeated MPCMessage messages = 1;
}

message NotificationChannel {
  string email = 1;
  string phone = 2;
  string push_token = 3;
}

message RegisterPartyRequest {
  string party_id = 1;
  string party_role = 2;
  string version = 3;
  NotificationChannel notification = 4;
}

message RegisterPartyResponse {
  bool success = 1;
  string message = 2;
  int64 registered_at = 3;
}

message SubscribeSessionEventsRequest {
  string party_id = 1;
  repeated string event_types = 2;
}

message SessionEvent {
  string event_id = 1;
  string event_type = 2;
  string session_id = 3;
  int32 threshold_n = 4;
  int32 threshold_t = 5;
  repeated string selected_parties = 6;
  map<string, string> join_tokens = 7;
  bytes message_hash = 8;
  int64 created_at = 9;
  int64 expires_at = 10;
}

message AcknowledgeMessageRequest {
  string message_id = 1;
  string party_id = 2;
  string session_id = 3;
  bool success = 4;
  string error_message = 5;
}

message AcknowledgeMessageResponse {
  bool success = 1;
  string message = 2;
}

message HeartbeatRequest {
  string party_id = 1;
  int64 timestamp = 2;
}

message HeartbeatResponse {
  bool success = 1;
  int64 server_timestamp = 2;
  int32 pending_messages = 3;
}

message DeviceInfo {
  string device_type = 1;
  string device_id = 2;
  string platform = 3;
  string app_version = 4;
}

message PartyInfo {
  string party_id = 1;
  int32 party_index = 2;
  DeviceInfo device_info = 3;
}

message SessionInfo {
  string session_id = 1;
  string session_type = 2;
  int32 threshold_n = 3;
  int32 threshold_t = 4;
  bytes message_hash = 5;
  string status = 6;
  string keygen_session_id = 7;
}

message JoinSessionRequest {
  string session_id = 1;
  string party_id = 2;
  string join_token = 3;
  DeviceInfo device_info = 4;
}

message JoinSessionResponse {
  bool success = 1;
  SessionInfo session_info = 2;
  repeated PartyInfo other_parties = 3;
  int32 party_index = 4;
}

message MarkPartyReadyRequest {
  string session_id = 1;
  string party_id = 2;
}

message MarkPartyReadyResponse {
  bool success = 1;
  bool all_ready = 2;
}

message ReportCompletionRequest {
  string session_id = 1;
  string party_id = 2;
  bytes public_key = 3;
  bytes signature = 4;
}

message ReportCompletionResponse {
  bool success = 1;
  bool all_completed = 2;
}

message GetSessionStatusRequest {
  string session_id = 1;
}

message GetSessionStatusResponse {
  string session_id = 1;
  string status = 2;
  int32 threshold_n = 3;
  int32 threshold_t = 4;
  repeated PartyInfo participants = 5;
}
