{
  "openapi": "3.1.0",
  "info": {
    "title": "Georoute API",
    "version": "0.1.0",
    "description": "Public room discovery and multiplayer game sessions for Georoute."
  },
  "servers": [{ "url": "https://georoutegame.com" }],
  "paths": {
    "/api/health": {
      "get": {
        "summary": "Check service health",
        "responses": { "200": { "description": "Healthy", "content": { "application/json": { "schema": { "type": "object", "properties": { "ok": { "const": true } }, "required": ["ok"] } } } } }
      }
    },
    "/api/rooms/public": {
      "get": {
        "summary": "List joinable public rooms",
        "responses": { "200": { "description": "Public rooms", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PublicRoom" } } } } } }
      }
    },
    "/api/rooms": {
      "post": {
        "summary": "Create a multiplayer room",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateRoom" } } } },
        "responses": { "201": { "description": "Room created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RoomSession" } } } }, "400": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/api/rooms/{code}": {
      "parameters": [{ "$ref": "#/components/parameters/RoomCode" }],
      "get": {
        "summary": "Get a room",
        "responses": { "200": { "description": "Room view", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RoomView" } } } }, "404": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/api/rooms/{code}/join": {
      "parameters": [{ "$ref": "#/components/parameters/RoomCode" }],
      "post": {
        "summary": "Join a room",
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "username": { "type": "string", "minLength": 2, "maxLength": 20 } }, "required": ["username"] } } } },
        "responses": { "200": { "description": "Room joined", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RoomSession" } } } }, "400": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/api/rooms/{code}/events": {
      "parameters": [{ "$ref": "#/components/parameters/RoomCode" }],
      "get": {
        "summary": "Stream room updates",
        "security": [{ "playerToken": [] }],
        "responses": { "200": { "description": "Server-sent room events", "content": { "text/event-stream": {} } }, "400": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/api/rooms/{code}/{action}": {
      "parameters": [
        { "$ref": "#/components/parameters/RoomCode" },
        { "name": "action", "in": "path", "required": true, "schema": { "type": "string", "enum": ["start", "next", "end"] } }
      ],
      "post": {
        "summary": "Perform a host room action",
        "security": [{ "playerToken": [] }],
        "responses": { "200": { "description": "Updated room", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RoomView" } } } }, "400": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/api/rooms/{code}/progress": {
      "parameters": [{ "$ref": "#/components/parameters/RoomCode" }],
      "post": {
        "summary": "Update a player's route",
        "security": [{ "playerToken": [] }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "hops": { "type": "array", "maxItems": 100, "items": { "$ref": "#/components/schemas/Hop" } }, "finished": { "type": "boolean" } }, "required": ["hops", "finished"] } } } },
        "responses": { "200": { "description": "Updated room", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RoomView" } } } }, "400": { "$ref": "#/components/responses/Error" } }
      }
    }
  },
  "components": {
    "securitySchemes": { "playerToken": { "type": "http", "scheme": "bearer", "description": "Opaque room-session token returned when a player creates or joins a room." } },
    "parameters": { "RoomCode": { "name": "code", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^[A-Z0-9_-]{6}$" } } },
    "responses": { "Error": { "description": "Request error", "content": { "application/json": { "schema": { "type": "object", "properties": { "error": { "type": "string" } }, "required": ["error"] } } } } },
    "schemas": {
      "Objective": { "type": "string", "enum": ["FASTEST", "CHEAPEST", "BUDGET"] },
      "PublicRoom": { "type": "object", "properties": { "code": { "type": "string" }, "origin": { "type": "string" }, "destination": { "type": "string" }, "objective": { "$ref": "#/components/schemas/Objective" }, "playerCount": { "type": "integer" } }, "required": ["code", "origin", "destination", "objective", "playerCount"] },
      "CreateRoom": { "type": "object", "properties": { "username": { "type": "string", "minLength": 2, "maxLength": 20 }, "visibility": { "type": "string", "enum": ["public", "private"] }, "origin": { "type": "string" }, "destination": { "type": "string" }, "objective": { "$ref": "#/components/schemas/Objective" }, "totalRounds": { "type": "integer", "enum": [3, 5, 10] }, "roundDurationSeconds": { "type": "integer", "enum": [120, 180, 300] } }, "required": ["username", "visibility", "origin", "destination", "objective"] },
      "Hop": { "type": "object", "properties": { "to": { "type": "string" }, "vehicle": { "type": "string", "enum": ["car", "boat", "ship", "plane", "helicopter"] } }, "required": ["to", "vehicle"] },
      "RoomView": { "type": "object", "description": "Current public room, puzzle, and player state. Shape may gain fields as the game evolves.", "additionalProperties": true },
      "RoomSession": { "type": "object", "properties": { "token": { "type": "string" }, "room": { "$ref": "#/components/schemas/RoomView" } }, "required": ["token", "room"] }
    }
  }
}
