import app/router
import app/web
import argv
import config
import gleam/erlang/process
import gleam/result
import glint
import mist
import player_manager
import session_manager
import socket_manager

pub type Error {
  ConfigError(config.ConfigError)
}

pub fn error_string(err: Error) -> String {
  case err {
    ConfigError(err) -> config.error_to_string(err)
  }
}

pub fn run_server() -> glint.Command(Result(Nil, Error)) {
  use <- glint.command_help("Runs the backend of Play of the Game")
  use _, args, _ <- glint.command()

  let cfg_path = case args {
    [] -> "config.toml"
    [cfg_path, ..] -> cfg_path
  }

  use cfg <- result.try(
    result.map_error(config.from_file(cfg_path), fn(err) {
      let err = ConfigError(err)
      err
    }),
  )

  let player_manager = player_manager.new()
  let socket_manager = socket_manager.new()
  let session_manager = session_manager.new(player_manager, socket_manager)

  let ctx =
    web.Context(
      config: cfg,
      players: player_manager,
      socket_manager:,
      sessions: session_manager,
    )

  let handler = router.handle_request(_, ctx)

  let assert Ok(_) =
    handler
    |> mist.new
    |> mist.bind(cfg.host)
    |> mist.port(cfg.port)
    |> mist.start_http

  process.sleep_forever()

  Ok(Nil)
}

pub fn main() {
  glint.new()
  |> glint.with_name("Play Of The Game")
  |> glint.pretty_help(glint.default_pretty_help())
  |> glint.add(at: [], do: run_server())
  |> glint.run(argv.load().arguments)
}
