#!/usr/bin/env bash
# Launch AAO in gateway mode (OpenAI-compatible LLM gateway, no UI).
#
# This is a sibling of scripts/server.sh (worker mode). Both can run
# concurrently on the same host because:
#   - PID file:    .gateway.pid     (worker uses .server.pid)
#   - Log file:    logs/gateway.log (worker uses logs/server.log)
#   - Listen port: $GATEWAY_PORT (default 4000)、worker は $PORT (default 9876)
#   - DB:          同じ data/aao.db を SQLite WAL mode で共有
#                  (gateway は gateway_virtual_keys + gateway_key_usage の 2 table のみ touch)
#
# Usage:
#   scripts/gateway.sh start
#   scripts/gateway.sh stop
#   scripts/gateway.sh restart
#   scripts/gateway.sh status
#   scripts/gateway.sh logs
#
# Env override:
#   GATEWAY_PORT=4000     # gateway.listen_port を上書き (config.yaml より優先)
#   AAO_CONFIG=/etc/aao/config-gateway.yaml  # 専用 config を使う場合
#   AAO_GATEWAY_NO_DB=1   # ステートレス起動 (virtual_keys は config 経由のみ、budget/rate-limit 無効)
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
PID_FILE="$PROJECT_DIR/.gateway.pid"
LOG_FILE="$PROJECT_DIR/logs/gateway.log"
GATEWAY_PORT="${GATEWAY_PORT:-4000}"

cd "$PROJECT_DIR"

usage() {
  echo "Usage: $0 {start|stop|restart|status|logs}"
  echo
  echo "Env:"
  echo "  GATEWAY_PORT=$GATEWAY_PORT"
  echo "  AAO_CONFIG=${AAO_CONFIG:-<repo config.yaml>}"
  echo "  AAO_GATEWAY_NO_DB=${AAO_GATEWAY_NO_DB:-<unset, DB enabled>}"
  exit 1
}

is_running() {
  if [[ -f "$PID_FILE" ]]; then
    local pid
    pid=$(cat "$PID_FILE")
    if kill -0 "$pid" 2>/dev/null; then
      return 0
    fi
    rm -f "$PID_FILE"
  fi
  return 1
}

do_start() {
  if is_running; then
    echo "Gateway already running (PID $(cat "$PID_FILE"))"
    return 0
  fi

  mkdir -p "$(dirname "$LOG_FILE")"

  echo "Checking runtime dependencies..."
  "$SCRIPT_DIR/prepare.sh"

  echo "Building..."
  npm run build --silent 2>&1 | tail -1

  echo "Starting gateway on port $GATEWAY_PORT..."
  # AAO_MODE=gateway は src/main.ts の switch を gateway/bootstrap に向ける
  # GATEWAY_PORT は src/gateway/config.ts が config.yaml の listen_port を
  # env で上書きするためのキー (実装側で env > config の precedence)。
  AAO_MODE=gateway \
    GATEWAY_PORT="$GATEWAY_PORT" \
    ${AAO_CONFIG:+AAO_CONFIG="$AAO_CONFIG"} \
    ${AAO_GATEWAY_NO_DB:+AAO_GATEWAY_NO_DB="$AAO_GATEWAY_NO_DB"} \
    nohup node dist/main.js >> "$LOG_FILE" 2>&1 &
  local pid=$!
  echo "$pid" > "$PID_FILE"

  # Wait briefly and verify it started
  sleep 2
  if kill -0 "$pid" 2>/dev/null; then
    echo "Gateway started (PID $pid, log: $LOG_FILE)"
    echo "  Health:  curl http://localhost:$GATEWAY_PORT/health/liveness"
    echo "  Metrics: curl http://localhost:$GATEWAY_PORT/metrics"
  else
    rm -f "$PID_FILE"
    echo "Gateway failed to start. Last 20 log lines:"
    tail -20 "$LOG_FILE"
    return 1
  fi
}

do_stop() {
  if ! is_running; then
    echo "Gateway not running"
    # Also kill any stray process on the port
    local stray
    stray=$(lsof -ti:"$GATEWAY_PORT" 2>/dev/null || true)
    if [[ -n "$stray" ]]; then
      echo "Found stray process on port $GATEWAY_PORT (PID $stray), killing..."
      kill "$stray" 2>/dev/null || true
    fi
    return 0
  fi

  local pid
  pid=$(cat "$PID_FILE")
  echo "Stopping gateway (PID $pid)..."
  # SIGTERM で graceful shutdown (gateway.shutdown_graceful_sec で SSE drain)
  kill "$pid" 2>/dev/null || true

  # Wait for graceful shutdown — gateway drain may take up to ~30s by default
  for i in {1..60}; do
    if ! kill -0 "$pid" 2>/dev/null; then
      rm -f "$PID_FILE"
      echo "Gateway stopped (graceful)"
      return 0
    fi
    sleep 0.5
  done

  # Force kill
  echo "Graceful shutdown timed out; force killing..."
  kill -9 "$pid" 2>/dev/null || true
  rm -f "$PID_FILE"
  echo "Gateway stopped (forced)"
}

do_status() {
  if is_running; then
    local pid
    pid=$(cat "$PID_FILE")
    echo "Gateway running (PID $pid, port $GATEWAY_PORT)"
    # Probe liveness for confirmation
    if curl -sS -o /dev/null -w "%{http_code}" "http://localhost:$GATEWAY_PORT/health/liveness" 2>/dev/null | grep -q 200; then
      echo "  Liveness: OK"
    else
      echo "  Liveness: NOT OK (process up but endpoint not responding)"
    fi
  else
    echo "Gateway not running"
  fi
}

do_logs() {
  if [[ -f "$LOG_FILE" ]]; then
    tail -f "$LOG_FILE"
  else
    echo "No log file found at $LOG_FILE"
  fi
}

case "${1:-}" in
  start)   do_start ;;
  stop)    do_stop ;;
  restart) do_stop; do_start ;;
  status)  do_status ;;
  logs)    do_logs ;;
  *)       usage ;;
esac
