openapi: 3.0.0
info:
  title: Tower Defence Server
  description: An API for talking to the Tower Defence Server
  version: 0.0.1
servers:
  - url: /api/v1
  - url: http://localhost:8080/api/v1
security:
  - JWTAuth: [ ]

components:
  securitySchemes:
    JWTAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:
    #############################################
    #  UUID                                     #
    #############################################
    UUID:
      description: Unique identifier compatible with [RFC9562](https://datatracker.ietf.org/doc/html/rfc9562)
      type: string
      format: uuid
      example: f0981749-f550-46cd-b9ce-b6ca7cd0251f
    #############################################
    #  PlayerRegistrationData                   #
    #############################################
    PlayerRegistrationData:
      description: Data needed to create a new player
      type: object
      properties:
        username:
          type: string
        password:
          type: string
      required:
        - username
        - password
    #############################################
    #  PlayerLoginData                          #
    #############################################
    PlayerLoginData:
      description: Data needed to log a Player in
      type: object
      properties:
        username:
          type: string
        password:
          type: string
      required:
        - username
        - password
    #############################################
    #  PlayerLoginSession                       #
    #############################################
    PlayerLoginSession:
      description: Data needed to log a Player in
      type: object
      properties:
        username:
          type: string
        token:
          type: string
      required:
        - username
        - token
    #############################################
    #  AdminAuthInfo                            #
    #############################################
    ServerHealth:
      type: object
      properties:
        okay:
          type: boolean
      required:
        - okay
    #############################################
    #  AdminAuthInfo                            #
    #############################################
    AdminAuthInfo:
      type: object
      properties:
        username:
          type: string
      required:
        - username
    #############################################
    #  AdministratablePlayer                                   #
    #############################################
    AdministratablePlayer:
      description: a Player
      type: object
      properties:
        username:
          type: string
      required:
        - username
    #############################################
    #  PlayerFilter                             #
    #############################################
    PlayerFilter:
      description: Configuration data for query for the getting all players endpoint
      type: object
      properties:
        page:
          type: integer
          description: "Page number (zero-based index)."
        pageSize:
          type: integer
          description: "Number of players per page."
        sortBy:
          type: string
          description: "Field to sort by (default is username)."
        order:
          type: string
          enum: [ ascending, descending ]
          description: "Sorting order (asc or desc)."
        username:
          type: string
          description: "Filter players by username (case-insensitive, partial match)."
      required:
        - page
        - pageSize
        - order
  responses:
    201PlayerCreated:
      description: "201 - Player Created"
    401PlayerNameOrPasswordWrong:
      description: "401 - Player Name or Password is Wrong"
    401Unauthorized:
      description: "401 - Unauthorized"
    404NotFound:
      description: "Not Found"
      content:
        text/plain:
          schema:
            type: string
    409UsernameTaken:
      description: "409 - Username Taken"
      content:
        text/plain:
          schema:
            type: string
    409Conflict:
      description: "409 - Conflict"
      content:
        text/plain:
          schema:
            type: string
    500InternalError:
      description: "500 - Internal Server Error"
      content:
        text/plain:
          schema:
            type: string
    503ServiceUnavailable:
      description: "503 - Service Unavailable"
      content:
        text/plain:
          schema:
            type: string
paths:
  /player/register:
    post:
      operationId: "PlayerRegister"
      tags:
        - server
      description: "Endpoint for registering a new Player"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlayerRegistrationData"
      responses:
        201:
          $ref: "#/components/responses/201PlayerCreated"
        409:
          $ref: "#/components/responses/409UsernameTaken"
        500:
          $ref: "#/components/responses/500InternalError"
  /player/login:
    post:
      operationId: "PlayerLogin"
      tags:
        - server
      description: "Endpoint for logging a Player in"
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlayerLoginData"
      responses:
        200:
          description: "A Login Session, which can be used in the Webhook"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlayerLoginSession"
        401:
          $ref: "#/components/responses/401PlayerNameOrPasswordWrong"
        500:
          $ref: "#/components/responses/500InternalError"
  /server/health:
    get:
      operationId: "ServerGetHealthcheck"
      tags:
        - server
      description: "Endpoint for doing a Healthcheck of the Server"
      responses:
        200:
          description: "A Health-Report of the server"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ServerHealth"
        500:
          $ref: "#/components/responses/500InternalError"
        503:
          $ref: "#/components/responses/503ServiceUnavailable"
  /admin/authenticated:
    get:
      operationId: "AdminGetAuthenticated"
      tags:
        - admin
      description: "Endpoint for Checking if you're authenticated as an admin"
      responses:
        200:
          description: "A Minimal Admin Info for testing if the admin is logged in"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AdminAuthInfo"
        401:
          $ref: "#/components/responses/401Unauthorized"
        500:
          $ref: "#/components/responses/500InternalError"
        503:
          $ref: "#/components/responses/503ServiceUnavailable"
  /admin/players:
    post:
      operationId: "GetAllPlayers"
      tags:
        - admin
      summary: "Retrieve a paginated list of players"
      description: "Returns a paginat#ed list of players, optionally filtered by username."
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PlayerFilter"
      responses:
        200:
          description: "A List of all Player"
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/AdministratablePlayer"
        401:
          $ref: "#/components/responses/401Unauthorized"
        500:
          $ref: "#/components/responses/500InternalError"
        503:
          $ref: "#/components/responses/503ServiceUnavailable"