// order reflects model/order/Order data object
include "common.fbs";

namespace order;

enum Relation : byte {
  UNKNOWN = 0,
  WAR = 1,
  PEACE = 2
}

enum ShipGroupCargo : byte {
  UNKNOWN = 0,
  COL = 1,
  MAT = 2,
  CAP = 3
}

enum ShipGroupUpgradeTech : byte {
  UNKNOWN = 0,
  ALL = 1,
  DRIVE = 2,
  WEAPONS = 3,
  SHIELDS = 4,
  CARGO = 5
}

enum PlanetProduction : byte {
  UNKNOWN = 0,
  MAT = 1,
  CAP = 2,
  DRIVE = 3,
  WEAPONS = 4,
  SHIELDS = 5,
  CARGO = 6,
  SCIENCE = 7,
  SHIP = 8
}

enum PlanetRouteLoadType : byte {
  UNKNOWN = 0,
  MAT = 1,
  CAP = 2,
  COL = 3,
  EMP = 4
}

table CommandRaceQuit {}

table CommandRaceVote {
  acceptor: string;
}

table CommandRaceRelation {
  acceptor: string;
  relation: Relation = UNKNOWN;
}

table CommandShipClassCreate {
  name: string;
  drive: float64;
  armament: int64;
  weapons: float64;
  shields: float64;
  cargo: float64;
}

table CommandShipClassMerge {
  name: string;
  target: string;
}

table CommandShipClassRemove {
  name: string;
}

table CommandShipGroupBreak {
  id: string;
  new_id: string;
  quantity: int64;
}

table CommandShipGroupLoad {
  id: string;
  cargo: ShipGroupCargo = UNKNOWN;
  quantity: float64;
}

table CommandShipGroupUnload {
  id: string;
  quantity: float64;
}

table CommandShipGroupSend {
  id: string;
  destination: int64;
}

table CommandShipGroupUpgrade {
  id: string;
  tech: ShipGroupUpgradeTech = UNKNOWN;
  level: float64;
}

table CommandShipGroupMerge {}

table CommandShipGroupDismantle {
  id: string;
}

table CommandShipGroupTransfer {
  id: string;
  acceptor: string;
}

table CommandShipGroupJoinFleet {
  id: string;
  name: string;
}

table CommandFleetMerge {
  name: string;
  target: string;
}

table CommandFleetSend {
  name: string;
  destination: int64;
}

table CommandScienceCreate {
  name: string;
  drive: float64;
  weapons: float64;
  shields: float64;
  cargo: float64;
}

table CommandScienceRemove {
  name: string;
}

table CommandPlanetRename {
  number: int64;
  name: string;
}

table CommandPlanetProduce {
  number: int64;
  production: PlanetProduction = UNKNOWN;
  subject: string;
}

table CommandPlanetRouteSet {
  origin: int64;
  destination: int64;
  load_type: PlanetRouteLoadType = UNKNOWN;
}

table CommandPlanetRouteRemove {
  origin: int64;
  load_type: PlanetRouteLoadType = UNKNOWN;
}

union CommandPayload {
  CommandRaceQuit,
  CommandRaceVote,
  CommandRaceRelation,
  CommandShipClassCreate,
  CommandShipClassMerge,
  CommandShipClassRemove,
  CommandShipGroupBreak,
  CommandShipGroupLoad,
  CommandShipGroupUnload,
  CommandShipGroupSend,
  CommandShipGroupUpgrade,
  CommandShipGroupMerge,
  CommandShipGroupDismantle,
  CommandShipGroupTransfer,
  CommandShipGroupJoinFleet,
  CommandFleetMerge,
  CommandFleetSend,
  CommandScienceCreate,
  CommandScienceRemove,
  CommandPlanetRename,
  CommandPlanetProduce,
  CommandPlanetRouteSet,
  CommandPlanetRouteRemove
}

table CommandItem {
  cmd_id: string;
  cmd_applied: bool = null;
  cmd_error_code: int64 = null;
  payload: CommandPayload (required);
}

// UserGamesCommand is the signed-gRPC request payload for
// `MessageTypeUserGamesCommand`. game_id selects the target running
// game; gateway re-encodes commands into the engine JSON shape and
// forwards through `POST /api/v1/user/games/{game_id}/commands`.
table UserGamesCommand {
  game_id: common.UUID (required);
  commands: [CommandItem];
}

// UserGamesOrder is the signed-gRPC request payload for
// `MessageTypeUserGamesOrder`. Identical to UserGamesCommand but
// carries `updated_at` so the order-validate path can reject stale
// submissions.
table UserGamesOrder {
  game_id: common.UUID (required);
  updated_at: int64;
  commands: [CommandItem];
}

// UserGamesCommandResponse is the success acknowledgement returned
// for `MessageTypeUserGamesCommand`. The engine answers with
// `204 No Content` on success, so the FB shape is intentionally empty
// — kept as a typed envelope for future extension.
table UserGamesCommandResponse {}

// UserGamesOrderResponse mirrors the engine's `PUT /api/v1/order`
// success body: it echoes the stored order back to the caller with
// the engine-assigned `updated_at` timestamp and per-command
// `cmd_applied` / `cmd_error_code` populated on every entry.
table UserGamesOrderResponse {
  game_id: common.UUID;
  updated_at: int64;
  commands: [CommandItem];
}

// UserGamesOrderGet is the signed-gRPC request payload for
// `MessageTypeUserGamesOrderGet`. Fetches the player's stored order
// for the given turn — the caller always knows the current turn from
// the lobby record so `turn` is required and must be non-negative.
table UserGamesOrderGet {
  game_id: common.UUID (required);
  turn: int64;
}

// UserGamesOrderGetResponse carries the result of
// `MessageTypeUserGamesOrderGet`. `found = false` is how the FBS
// envelope conveys the engine's `204 No Content` (no order stored
// for this player on this turn). When `found = true`, `order` is
// the engine's stored order for the turn.
table UserGamesOrderGetResponse {
  found: bool;
  order: UserGamesOrder;
}
