#!/usr/bin/env bash
set -euo pipefail

ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)

LOG_DIR=${HM_LOG_DIR:-"$ROOT_DIR/hm_log"}
GAMESERVER_IP=${HM_GAMESERVER_IP:-"127.0.0.1"}
GAMESERVER_PORT=${HM_GAMESERVER_PORT:-"3724"}

GAMESERVER_BIN="$ROOT_DIR/hm_gameserver/hm_gameserver"
LOBBYSERVER_BIN="$ROOT_DIR/hm_lobbyserver/hm_lobbyserver"

GAMESERVER_PID="$LOG_DIR/hm_gameserver.pid"
LOBBYSERVER_PID="$LOG_DIR/hm_lobbyserver.pid"

usage() {
    cat <<EOF
Usage: ./dev <command>

Commands:
  build            Build gameserver and lobbyserver
  start            Start gameserver and lobbyserver
  stop             Stop running servers
  status           Show server status
  logs             Tail server logs
  docker-build     Build docker images
  docker-start     Start dockerized stack
  docker-stop      Stop dockerized stack
  docker-status    Show docker stack status
  docker-logs      Tail dockerized logs

Environment:
  HM_LOG_DIR            Log directory (default: ./hm_log)
  HM_GAMESERVER_IP      Lobby points to this IP (default: 127.0.0.1)
  HM_GAMESERVER_PORT    Lobby points to this port (default: 3724)
  HM_SKIP_COUCHBASE_CHECK=1  Skip Couchbase availability check
EOF
}

docker_compose() {
    if command -v docker >/dev/null 2>&1 && docker compose version >/dev/null 2>&1; then
        docker compose "$@"
        return
    fi

    if command -v docker-compose >/dev/null 2>&1; then
        docker-compose "$@"
        return
    fi

    echo "docker compose not found" >&2
    exit 1
}

require_bin() {
    if ! command -v "$1" >/dev/null 2>&1; then
        echo "Missing required binary: $1" >&2
        exit 1
    fi
}

check_couchbase() {
    if [ "${HM_SKIP_COUCHBASE_CHECK:-}" = "1" ]; then
        return 0
    fi

    if command -v curl >/dev/null 2>&1; then
        if ! curl -s --max-time 2 http://localhost:8091/pools >/dev/null; then
            echo "Couchbase not reachable on localhost:8091." >&2
            echo "Start Couchbase and restore bucket 'hbs' or set HM_SKIP_COUCHBASE_CHECK=1." >&2
            exit 1
        fi
    else
        echo "curl not found; cannot verify Couchbase availability." >&2
        echo "Install curl or set HM_SKIP_COUCHBASE_CHECK=1." >&2
        exit 1
    fi
}

build() {
    require_bin make
    make -C "$ROOT_DIR/hm_gameserver"
    make -C "$ROOT_DIR/hm_lobbyserver"
}

start() {
    check_couchbase
    mkdir -p "$LOG_DIR"

    if [ ! -x "$GAMESERVER_BIN" ] || [ ! -x "$LOBBYSERVER_BIN" ]; then
        echo "Binaries missing; run ./dev build first." >&2
        exit 1
    fi

    if [ -f "$GAMESERVER_PID" ] || [ -f "$LOBBYSERVER_PID" ]; then
        echo "PID files exist; run ./dev stop first." >&2
        exit 1
    fi

    nohup "$GAMESERVER_BIN" > "$LOG_DIR/hm_gameserver.out" 2>&1 &
    echo $! > "$GAMESERVER_PID"

    nohup "$LOBBYSERVER_BIN" \
        --gameserver="$GAMESERVER_IP" \
        --gameserver_port="$GAMESERVER_PORT" \
        > "$LOG_DIR/hm_lobbyserver.out" 2>&1 &
    echo $! > "$LOBBYSERVER_PID"

    echo "Servers started. Logs in $LOG_DIR"
}

stop() {
    if [ -f "$GAMESERVER_PID" ]; then
        kill "$(cat "$GAMESERVER_PID")" 2>/dev/null || true
        rm -f "$GAMESERVER_PID"
    fi

    if [ -f "$LOBBYSERVER_PID" ]; then
        kill "$(cat "$LOBBYSERVER_PID")" 2>/dev/null || true
        rm -f "$LOBBYSERVER_PID"
    fi
}

status() {
    if [ -f "$GAMESERVER_PID" ] && kill -0 "$(cat "$GAMESERVER_PID")" 2>/dev/null; then
        echo "hm_gameserver running (pid $(cat "$GAMESERVER_PID"))"
    else
        echo "hm_gameserver not running"
    fi

    if [ -f "$LOBBYSERVER_PID" ] && kill -0 "$(cat "$LOBBYSERVER_PID")" 2>/dev/null; then
        echo "hm_lobbyserver running (pid $(cat "$LOBBYSERVER_PID"))"
    else
        echo "hm_lobbyserver not running"
    fi
}

logs() {
    tail -f "$LOG_DIR/hm_gameserver.out" "$LOG_DIR/hm_lobbyserver.out"
}

case "${1:-}" in
    build)
        build
        ;;
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    logs)
        logs
        ;;
    docker-build)
        docker_compose build
        ;;
    docker-start)
        docker_compose up -d
        ;;
    docker-stop)
        docker_compose down
        ;;
    docker-status)
        docker_compose ps
        ;;
    docker-logs)
        docker_compose logs -f --tail=200 gameserver lobbyserver
        ;;
    *)
        usage
        exit 1
        ;;
esac
