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

PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}"
COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-easyai-ai-gateway}"
AI_GATEWAY_PLATFORM="${AI_GATEWAY_PLATFORM:-linux/amd64}"
AI_GATEWAY_IMAGE_REGISTRY="${AI_GATEWAY_IMAGE_REGISTRY:-registry.cn-shanghai.aliyuncs.com/easyaigc}"
AI_GATEWAY_IMAGE_TAG="${AI_GATEWAY_IMAGE_TAG:-local}"
AI_GATEWAY_API_IMAGE="${AI_GATEWAY_API_IMAGE:-${AI_GATEWAY_IMAGE_REGISTRY}/ai-gateway:${AI_GATEWAY_IMAGE_TAG}}"
AI_GATEWAY_WEB_IMAGE="${AI_GATEWAY_WEB_IMAGE:-${AI_GATEWAY_IMAGE_REGISTRY}/ai-gateway-web:${AI_GATEWAY_IMAGE_TAG}}"
ACTION="${1:-deploy}"

export COMPOSE_PROJECT_NAME
export AI_GATEWAY_PLATFORM
export AI_GATEWAY_API_IMAGE
export AI_GATEWAY_WEB_IMAGE
export DOCKER_DEFAULT_PLATFORM="${DOCKER_DEFAULT_PLATFORM:-$AI_GATEWAY_PLATFORM}"

compose=(docker compose -f "$COMPOSE_FILE")

usage() {
  cat <<'EOF'
Usage:
  scripts/deploy-compose.sh          Build, migrate, start, and verify locally
  scripts/deploy-compose.sh deploy   Same as default
  scripts/deploy-compose.sh down     Stop containers, keep volumes
  scripts/deploy-compose.sh clean    Stop containers and remove volumes

Useful environment overrides:
  AI_GATEWAY_PLATFORM=linux/amd64
  AI_GATEWAY_IMAGE_TAG=2026.05.23-1
  AI_GATEWAY_API_IMAGE=registry.cn-shanghai.aliyuncs.com/easyaigc/ai-gateway:2026.05.23-1
  AI_GATEWAY_WEB_IMAGE=registry.cn-shanghai.aliyuncs.com/easyaigc/ai-gateway-web:2026.05.23-1
  AI_GATEWAY_WEB_PORT=5178
  AI_GATEWAY_API_PORT=8088
  AI_GATEWAY_DB_PORT=54329
  AI_GATEWAY_SKIP_BUILD=1

Production publishing is intentionally unavailable here. Use:
  scripts/publish-release-images.sh --components auto
EOF
}

fail_with_logs() {
  echo "[ai-gateway] deployment failed; recent container state follows" >&2
  "${compose[@]}" ps >&2 || true
  "${compose[@]}" logs --tail=160 postgres migrator api web >&2 || true
  exit 1
}

remove_stale_migrator() {
  "${compose[@]}" rm -sf migrator >/dev/null 2>&1 || true
}

wait_for_service_healthy() {
  local service="$1"
  local container_id=""
  local status=""

  for _ in $(seq 1 60); do
    container_id="$("${compose[@]}" ps -q "$service" 2>/dev/null || true)"
    if [[ -n "$container_id" ]]; then
      status="$(docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "$container_id" 2>/dev/null || true)"
      if [[ "$status" == "healthy" || "$status" == "running" ]]; then
        echo "[ai-gateway] ${service} is ${status}"
        return 0
      fi
      if [[ "$status" == "exited" || "$status" == "dead" ]]; then
        echo "[ai-gateway] ${service} stopped while waiting for health" >&2
        fail_with_logs
      fi
    fi
    sleep 2
  done

  echo "[ai-gateway] timed out waiting for ${service} to become healthy" >&2
  fail_with_logs
}

wait_for_http() {
  local label="$1"
  local url="$2"
  local expected="${3:-}"
  local body=""

  for _ in $(seq 1 60); do
    if body="$(curl -fsS --max-time 5 "$url" 2>/dev/null)"; then
      if [[ -z "$expected" || "$body" == *"$expected"* ]]; then
        echo "[ai-gateway] verified ${label}: ${url}"
        return 0
      fi
    fi
    sleep 2
  done

  echo "[ai-gateway] timed out waiting for ${label}: ${url}" >&2
  [[ -n "$body" ]] && echo "$body" >&2
  fail_with_logs
}

published_port() {
  local service="$1"
  local private_port="$2"
  local fallback="$3"
  local endpoint=""

  endpoint="$("${compose[@]}" port "$service" "$private_port" 2>/dev/null | tail -n 1 || true)"
  if [[ -n "$endpoint" ]]; then
    echo "${endpoint##*:}"
  else
    echo "$fallback"
  fi
}

build_images() {
  if [[ "${AI_GATEWAY_SKIP_BUILD:-0}" != "1" ]]; then
    echo "[ai-gateway] building images"
    echo "[ai-gateway] api image: ${AI_GATEWAY_API_IMAGE}"
    echo "[ai-gateway] web image: ${AI_GATEWAY_WEB_IMAGE}"
    "${compose[@]}" build --pull
  else
    echo "[ai-gateway] skipping image build"
  fi
}

deploy() {
  cd "$PROJECT_ROOT"

  command -v docker >/dev/null 2>&1 || {
    echo "[ai-gateway] docker is required" >&2
    exit 1
  }
  docker compose version >/dev/null 2>&1 || {
    echo "[ai-gateway] docker compose v2 is required" >&2
    exit 1
  }
  command -v curl >/dev/null 2>&1 || {
    echo "[ai-gateway] curl is required for deployment verification" >&2
    exit 1
  }

  echo "[ai-gateway] compose project: ${COMPOSE_PROJECT_NAME}"
  echo "[ai-gateway] target platform: ${AI_GATEWAY_PLATFORM}"
  echo "[ai-gateway] image tag: ${AI_GATEWAY_IMAGE_TAG}"

  build_images

  echo "[ai-gateway] starting postgres"
  "${compose[@]}" up -d postgres
  wait_for_service_healthy postgres

  echo "[ai-gateway] running database migrations"
  remove_stale_migrator
  "${compose[@]}" run --rm migrator
  remove_stale_migrator

  echo "[ai-gateway] starting api and web"
  "${compose[@]}" up -d api web

  local api_port
  local web_port
  api_port="$(published_port api 8088 "${AI_GATEWAY_API_PORT:-8088}")"
  web_port="$(published_port web 80 "${AI_GATEWAY_WEB_PORT:-5178}")"

  wait_for_http "api health" "http://127.0.0.1:${api_port}/api/v1/healthz" "easyai-ai-gateway"
  wait_for_http "api readiness" "http://127.0.0.1:${api_port}/api/v1/readyz" '"ok":true'
  wait_for_http "web reverse proxy" "http://127.0.0.1:${web_port}/api/v1/healthz" "easyai-ai-gateway"
  wait_for_http "web app" "http://127.0.0.1:${web_port}/" "EasyAI AI Gateway"

  echo "[ai-gateway] deployment succeeded"
  echo "[ai-gateway] Web: http://127.0.0.1:${web_port}"
  echo "[ai-gateway] API: http://127.0.0.1:${api_port}/api/v1/healthz"
}

case "$ACTION" in
  deploy|up)
    deploy
    ;;
  down)
    cd "$PROJECT_ROOT"
    "${compose[@]}" down --remove-orphans
    ;;
  clean)
    cd "$PROJECT_ROOT"
    "${compose[@]}" down -v --remove-orphans
    ;;
  -h|--help|help)
    usage
    ;;
  *)
    usage >&2
    exit 2
    ;;
esac
