syntax = "proto3";

/*********** PARTIAL MESSAGES **************/

message PositionMessage {
  int32 x = 1;
  int32 y = 2;
  enum Direction {
    UP = 0;
    RIGHT = 1;
    DOWN = 2;
    LEFT = 3;
  }
  Direction direction = 3;
  bool moving = 4;
}

message PointMessage {
  int32 x = 1;
  int32 y = 2;
}

message ViewportMessage {
  int32 left = 1;
  int32 top = 2;
  int32 right = 3;
  int32 bottom = 4;
}

message SilentMessage {
  bool silent = 1;
}

message CharacterLayerMessage {
  string url = 1;
  string name = 2;
}

/*********** CLIENT TO SERVER MESSAGES *************/

message PingMessage {

}

message SetPlayerDetailsMessage {
  string name = 1;
  repeated string characterLayers = 2;
}

message UserMovesMessage {
  PositionMessage position = 1;
  ViewportMessage viewport = 2;
}

message WebRtcSignalToServerMessage {
  int32 receiverId = 1;
  string signal = 2;
}

message ReportPlayerMessage {
  int32 reportedUserId = 1;
  string reportComment = 2;
}

message QueryJitsiJwtMessage {
  string jitsiRoom = 1;
  string tag = 2; // FIXME: rather than reading the tag from the query, we should read it from the current map!
}

message ClientToServerMessage {
  oneof message {
    UserMovesMessage userMovesMessage = 2;
    SilentMessage silentMessage = 3;
    ViewportMessage viewportMessage = 4;
    ItemEventMessage itemEventMessage = 5;
    SetPlayerDetailsMessage setPlayerDetailsMessage = 6;
    WebRtcSignalToServerMessage webRtcSignalToServerMessage = 7;
    WebRtcSignalToServerMessage webRtcScreenSharingSignalToServerMessage = 8;
    PlayGlobalMessage playGlobalMessage = 9;
    StopGlobalMessage stopGlobalMessage = 10;
    ReportPlayerMessage reportPlayerMessage = 11;
    QueryJitsiJwtMessage queryJitsiJwtMessage = 12;
  }
}


/************ BI-DIRECTIONAL MESSAGES **************/

message ItemEventMessage {
  int32 itemId = 1;
  string event = 2;
  string stateJson = 3;
  string parametersJson = 4;
}

message PlayGlobalMessage {
  string id = 1;
  string type = 2;
  string message = 3;
}

message StopGlobalMessage {
  string id = 1;
}

/*********** SERVER TO CLIENT MESSAGES *************/

message UserMovedMessage {
  int32 userId = 1;
  PositionMessage position = 2;
}

message SubMessage {
  oneof message {
    UserMovedMessage userMovedMessage = 1;
    GroupUpdateMessage groupUpdateMessage = 2;
    GroupDeleteMessage groupDeleteMessage = 3;
    UserJoinedMessage userJoinedMessage = 4;
    UserLeftMessage userLeftMessage = 5;
    ItemEventMessage itemEventMessage = 6;
  }
}

message BatchMessage {
  string event = 1;
  repeated SubMessage payload = 2;
}

message GroupUpdateMessage {
  int32 groupId = 1;
  PointMessage position = 2;
  int32 groupSize = 3;
}

message GroupDeleteMessage {
  int32 groupId = 1;
}

message UserJoinedMessage {
  int32 userId = 1;
  string name = 2;
  repeated CharacterLayerMessage characterLayers = 3;
  PositionMessage position = 4;
}

message UserLeftMessage {
  int32 userId = 1;
}

message ErrorMessage {
  string message = 1;
}

message ItemStateMessage {
  int32 itemId = 1;
  string stateJson = 2;
}

message RoomJoinedMessage {
  //repeated UserJoinedMessage user = 1;
  //repeated GroupUpdateMessage group = 2;
  repeated ItemStateMessage item = 3;
  int32 currentUserId = 4;
  repeated string tag = 5;
}

message WebRtcStartMessage {
  int32 userId = 1;
  string name = 2;
  bool initiator = 3;
}

message WebRtcDisconnectMessage {
  int32 userId = 1;
}

message WebRtcSignalToClientMessage {
  int32 userId = 1;
  string signal = 2;
}

message TeleportMessageMessage{
  string map = 1;
}

message SendJitsiJwtMessage {
  string jitsiRoom = 1;
  string jwt = 2;
}

message SendUserMessage{
  string type = 1;
  string message = 2;
}

message ServerToClientMessage {
  oneof message {
    BatchMessage batchMessage = 1;
    ErrorMessage errorMessage = 2;
    RoomJoinedMessage roomJoinedMessage = 3;
    WebRtcStartMessage webRtcStartMessage = 4;
    WebRtcSignalToClientMessage webRtcSignalToClientMessage = 5;
    WebRtcSignalToClientMessage webRtcScreenSharingSignalToClientMessage = 6;
    WebRtcDisconnectMessage webRtcDisconnectMessage = 7;
    PlayGlobalMessage playGlobalMessage = 8;
    StopGlobalMessage stopGlobalMessage = 9;
    TeleportMessageMessage teleportMessageMessage = 10;
    SendJitsiJwtMessage sendJitsiJwtMessage = 11;
    SendUserMessage sendUserMessage = 12;
  }
}


/************************** SERVICES **************************/

message JoinRoomMessage {
  PositionMessage positionMessage = 1;
  string name = 2;
  repeated CharacterLayerMessage characterLayer = 3;
  string userUuid = 4;
  string roomId = 5;
  repeated string tag = 6;
}

message UserJoinedZoneMessage {
  int32 userId = 1;
  string name = 2;
  repeated CharacterLayerMessage characterLayers = 3;
  PositionMessage position = 4;
  Zone fromZone = 5;
}

message UserLeftZoneMessage {
  int32 userId = 1;
  Zone toZone = 2;
}

message GroupUpdateZoneMessage {
  int32 groupId = 1;
  PointMessage position = 2;
  int32 groupSize = 3;
  Zone fromZone = 4;
}

message GroupLeftZoneMessage {
  int32 groupId = 1;
  Zone toZone = 2;
}


message Zone {
  int32 x = 1;
  int32 y = 2;
}

message ZoneMessage {
  string roomId = 1;
  int32 x = 2;
  int32 y = 3;
}

message PusherToBackMessage {
  oneof message {
    JoinRoomMessage joinRoomMessage = 1;
    UserMovesMessage userMovesMessage = 2;
    SilentMessage silentMessage = 3;
    ItemEventMessage itemEventMessage = 4;
    SetPlayerDetailsMessage setPlayerDetailsMessage = 5;
    WebRtcSignalToServerMessage webRtcSignalToServerMessage = 6;
    WebRtcSignalToServerMessage webRtcScreenSharingSignalToServerMessage = 7;
    PlayGlobalMessage playGlobalMessage = 8;
    StopGlobalMessage stopGlobalMessage = 9;
    ReportPlayerMessage reportPlayerMessage = 10;
    QueryJitsiJwtMessage queryJitsiJwtMessage = 11;
  }
}

message BatchToPusherMessage {
  repeated SubToPusherMessage payload = 2;
}

message SubToPusherMessage {
  oneof message {
    UserJoinedZoneMessage userJoinedZoneMessage = 1;
    GroupUpdateZoneMessage groupUpdateZoneMessage = 2;
    UserMovedMessage userMovedMessage = 3;
    GroupLeftZoneMessage groupLeftZoneMessage = 4;
    UserLeftZoneMessage userLeftZoneMessage = 5;
    ItemEventMessage itemEventMessage = 6;
    SendUserMessage sendUserMessage = 7;
  }
}

/*message BatchToAdminPusherMessage {
  repeated SubToAdminPusherMessage payload = 2;
}*/

/*message SubToAdminPusherMessage {
  oneof message {
    string userUuidJoinedRoom = 1;
    string userUuidLeftRoom = 2;
  }
}

message ServerToAdminClientMessage {
  repeated SubToAdminPusherMessage payload = 2;
}*/

message ServerToAdminClientMessage {
  oneof message {
    string userUuidJoinedRoom = 1;
    string userUuidLeftRoom = 2;
  }
}

message AdminPusherToBackMessage {
  oneof message {
    string subscribeToRoom = 1;
    // TODO ban, unban
  }
}

// A message sent by an administrator to a recipient
message AdminMessage {
  string message = 1;
  string recipientUuid = 2;
  string roomId = 3;
}

// A message sent by an administrator to absolutely everybody
message AdminGlobalMessage {
  string message = 1;
}

message BanMessage {
  string recipientUuid = 1;
  string roomId = 2;
}

message EmptyMessage {

}

service RoomManager {
  rpc joinRoom(stream PusherToBackMessage) returns (stream ServerToClientMessage);
  rpc listenZone(ZoneMessage) returns (stream BatchToPusherMessage);
  rpc adminRoom(stream AdminPusherToBackMessage) returns (stream ServerToAdminClientMessage);
  rpc sendAdminMessage(AdminMessage) returns (EmptyMessage);
  rpc sendGlobalAdminMessage(AdminGlobalMessage) returns (EmptyMessage);
  rpc ban(BanMessage) returns (EmptyMessage);
}
