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

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
TESTPROJECT="$REPO_ROOT/testproject"

# Load .env from repo root if present (secrets like LLM_HANDLER_API_KEY)
if [ -f "$REPO_ROOT/.env" ]; then
    set -a
    source "$REPO_ROOT/.env"
    set +a
fi

# Use venv Python if available
if [ -f "$REPO_ROOT/.venv/bin/python" ]; then
    PYTHON="$REPO_ROOT/.venv/bin/python"
else
    PYTHON="python3"
fi

PIDFILE="$TESTPROJECT/var/asgi.pid"
LOGFILE="$TESTPROJECT/var/asgi.log"

_check_project() {
    if [ ! -d "$TESTPROJECT" ]; then
        echo "ERROR: testproject/ not found. Run ./bin/create_testproject first."
        exit 1
    fi
    mkdir -p "$TESTPROJECT/var"
}

_ensure_redis() {
    # Look for redis-cli in PATH, then common Homebrew locations
    REDIS_CLI="redis-cli"
    REDIS_SERVER="redis-server"
    for dir in /opt/homebrew/bin /usr/local/bin; do
        if [ -x "$dir/redis-cli" ]; then
            REDIS_CLI="$dir/redis-cli"
            REDIS_SERVER="$dir/redis-server"
            break
        fi
    done

    if ! "$REDIS_CLI" ping > /dev/null 2>&1; then
        echo "==> Starting redis-server in background"
        "$REDIS_SERVER" --daemonize yes
    fi
}

_read_conf() {
    HOST="127.0.0.1"
    PORT="5555"
    CONF="$TESTPROJECT/config/dev_server.conf"
    if [ -f "$CONF" ]; then
        while IFS='=' read -r key value; do
            key=$(echo "$key" | tr -d '[:space:]')
            value=$(echo "$value" | tr -d '[:space:]')
            case "$key" in
                host) HOST="$value" ;;
                port) PORT="$value" ;;
            esac
        done < "$CONF"
    fi
    export DJANGO_SETTINGS_MODULE=settings
    export PYTHONUNBUFFERED=1
}

_is_running() {
    if [ -f "$PIDFILE" ]; then
        pid=$(cat "$PIDFILE")
        if kill -0 "$pid" 2>/dev/null; then
            return 0
        fi
        # stale pid file
        rm -f "$PIDFILE"
    fi
    return 1
}

_run_migrations() {
    echo "==> Running migrations"
    # If django_migrations is empty (e.g. after test flush), fake first then apply real
    EMPTY=$( DJANGO_SETTINGS_MODULE=settings PYTHONPATH="$TESTPROJECT/config:$REPO_ROOT" \
        $PYTHON -c "
import django; django.setup()
from django.db import connection
c = connection.cursor()
c.execute('SELECT COUNT(*) FROM django_migrations')
print(c.fetchone()[0])
" 2>/dev/null || echo "0" )

    if [ "$EMPTY" = "0" ]; then
        echo "    Migration tracker empty — faking existing then applying new"
        DJANGO_SETTINGS_MODULE=settings PYTHONPATH="$TESTPROJECT/config:$REPO_ROOT" \
            $PYTHON -m django migrate --fake --settings=settings --no-input 2>&1 | tail -3
        DJANGO_SETTINGS_MODULE=settings PYTHONPATH="$TESTPROJECT/config:$REPO_ROOT" \
            $PYTHON -m django makemigrations --settings=settings --no-input 2>&1 | tail -3
        DJANGO_SETTINGS_MODULE=settings PYTHONPATH="$TESTPROJECT/config:$REPO_ROOT" \
            $PYTHON -m django migrate --settings=settings --no-input 2>&1 | tail -3
    else
        DJANGO_SETTINGS_MODULE=settings PYTHONPATH="$TESTPROJECT/config:$REPO_ROOT" \
            $PYTHON -m django migrate --settings=settings --no-input 2>&1 | tail -5
    fi
}

do_start() {
    _check_project
    _ensure_redis
    _read_conf

    if _is_running; then
        echo "Already running (PID $(cat "$PIDFILE"))"
        exit 0
    fi

    _run_migrations

    echo "==> Starting uvicorn on http://$HOST:$PORT (daemon)"
    nohup $PYTHON -m uvicorn _asgi:application \
        --app-dir "$TESTPROJECT/bin" \
        --host "$HOST" \
        --port "$PORT" \
        --reload \
        --reload-include '*.conf' \
        > "$LOGFILE" 2>&1 &

    echo $! > "$PIDFILE"
    echo "Started (PID $!, log: $LOGFILE)"
}

do_stop() {
    if ! _is_running; then
        echo "Not running"
        return 0
    fi
    pid=$(cat "$PIDFILE")
    echo "==> Stopping uvicorn (PID $pid)"
    kill "$pid" 2>/dev/null || true
    # wait up to 5s for graceful shutdown
    for i in $(seq 1 10); do
        if ! kill -0 "$pid" 2>/dev/null; then
            break
        fi
        sleep 0.5
    done
    # force kill if still alive
    if kill -0 "$pid" 2>/dev/null; then
        kill -9 "$pid" 2>/dev/null || true
    fi
    rm -f "$PIDFILE"
    echo "Stopped"
}

do_status() {
    if _is_running; then
        echo "Running (PID $(cat "$PIDFILE"))"
    else
        echo "Not running"
    fi
}

do_foreground() {
    _check_project
    _ensure_redis
    _read_conf
    _run_migrations

    if _is_running; then
        echo "WARNING: daemon already running (PID $(cat "$PIDFILE")), starting foreground anyway"
    fi

    echo "==> Starting uvicorn on http://$HOST:$PORT"
    exec $PYTHON -m uvicorn _asgi:application \
        --app-dir "$TESTPROJECT/bin" \
        --host "$HOST" \
        --port "$PORT" \
        --reload \
        --reload-include '*.conf'
}

case "${1:-}" in
    start)   do_start ;;
    stop)    do_stop ;;
    restart) do_stop; do_start ;;
    status)  do_status ;;
    "")      do_foreground ;;
    *)
        echo "Usage: asgi_local [start|stop|restart|status]"
        echo "  (no args)  Run in foreground"
        echo "  start      Run as background daemon"
        echo "  stop       Stop the daemon"
        echo "  restart    Restart the daemon"
        echo "  status     Check if running"
        exit 1
        ;;
esac
