#!/usr/bin/env bash
# ============================================================
# start-e2e-stack.sh
#
# 启动 L2 MCP E2E 测试栈：
#   - 后端  → port 3011，连接测试数据库（ts-node 直启）
#   - 前端  → port 3010，Docker 容器运行（避免与开发环境冲突）
#
# 用法：
#   bash testing/scripts/start-e2e-stack.sh          # 前台，Ctrl-C 停止
#   bash testing/scripts/start-e2e-stack.sh --daemon # 后台，PID 写入 /tmp/e2e-stack.pid
# ============================================================
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# shellcheck disable=SC1091
source "${ROOT_DIR}/testing/scripts/lib-test-db.sh"

DAEMON=false
[[ "${1:-}" == "--daemon" ]] && DAEMON=true

# ── 设置测试 DB 环境变量 ────────────────────────────────────
setup_test_db_env

E2E_BACKEND_PORT="${E2E_BACKEND_PORT:-3011}"
E2E_FRONTEND_PORT="${E2E_FRONTEND_PORT:-3010}"
E2E_BACKEND_URL="http://localhost:${E2E_BACKEND_PORT}"
E2E_FRONTEND_CONTAINER="ffoa-test-frontend"

PID_FILE="/tmp/e2e-stack.pid"

# ── 检查端口是否已被占用 ────────────────────────────────────
check_port() {
  local port=$1
  if lsof -ti tcp:"${port}" >/dev/null 2>&1; then
    echo "⚠️  端口 ${port} 已被占用，请先停止占用进程或修改 E2E_*_PORT 环境变量" >&2
    return 1
  fi
}

check_port "${E2E_BACKEND_PORT}"
check_port "${E2E_FRONTEND_PORT}"

echo "🚀 启动 E2E 测试栈"
echo "   Backend  → http://localhost:${E2E_BACKEND_PORT}"
echo "   Frontend → http://localhost:${E2E_FRONTEND_PORT} (Docker)"
echo "   Database → ${TEST_DATABASE_URL}"
echo ""

# ── 启动后端 ────────────────────────────────────────────────
# ts-node 直接启动，NODE_ENV=development 使 CORS 允许所有来源
start_backend() {
  cd "${ROOT_DIR}/backend"
  DATABASE_URL="${TEST_DATABASE_URL}" \
  BACKEND_PORT="${E2E_BACKEND_PORT}" \
  NODE_ENV="development" \
    npx ts-node -r tsconfig-paths/register src/main.ts
}

# ── 启动前端（Docker）──────────────────────────────────────
# Docker 容器运行前端，与开发环境完全隔离：
#   - 源码只读挂载（:ro），防止容器写回宿主机
#   - .next 编译缓存使用独立命名卷，不与开发前端冲突
#   - node_modules 只读挂载，复用宿主机依赖
# 容器内通过 host.docker.internal 访问宿主机后端。
start_frontend_docker() {
  # 清理旧容器
  docker rm -f "${E2E_FRONTEND_CONTAINER}" 2>/dev/null || true

  # 检测宿主机 → 容器的网络地址
  local host_addr="host.docker.internal"
  # Linux 可能不支持 host.docker.internal，用 --add-host 方式
  local extra_host_flag="--add-host=host.docker.internal:host-gateway"

  docker run -d \
    --name "${E2E_FRONTEND_CONTAINER}" \
    ${extra_host_flag} \
    -p "${E2E_FRONTEND_PORT}:3000" \
    -v "${ROOT_DIR}/frontend/src:/app/src:ro" \
    -v "${ROOT_DIR}/frontend/public:/app/public:ro" \
    -v "${ROOT_DIR}/frontend/package.json:/app/package.json:ro" \
    -v "${ROOT_DIR}/frontend/tsconfig.json:/app/tsconfig.json:ro" \
    -v "${ROOT_DIR}/frontend/next.config.ts:/app/next.config.ts:ro" \
    -v "${ROOT_DIR}/frontend/tailwind.config.ts:/app/tailwind.config.ts:ro" \
    -v "${ROOT_DIR}/frontend/postcss.config.mjs:/app/postcss.config.mjs:ro" \
    -v "${ROOT_DIR}/frontend/components.json:/app/components.json:ro" \
    -v "${ROOT_DIR}/frontend/node_modules:/app/node_modules:ro" \
    -v "${E2E_FRONTEND_CONTAINER}-next:/app/.next" \
    -w /app \
    -e "NEXT_PUBLIC_API_URL=http://localhost:${E2E_BACKEND_PORT}/api/v1" \
    -e "NEXT_PUBLIC_API_BASE_URL=http://${host_addr}:${E2E_BACKEND_PORT}" \
    node:20 \
    sh -c "rm -f .next/dev/lock && npx next dev -p 3000"
}

# ── 停止前端容器 ──────────────────────────────────────────
stop_frontend_docker() {
  docker rm -f "${E2E_FRONTEND_CONTAINER}" 2>/dev/null || true
}

if $DAEMON; then
  echo "🔧 后台模式启动..."

  start_backend >> /tmp/e2e-backend.log 2>&1 &
  BACKEND_PID=$!

  # 等待后端就绪（最多 40s）
  echo -n "   等待后端就绪..."
  for i in $(seq 1 40); do
    if curl -sf "${E2E_BACKEND_URL}/api/v1/auth/login" -X POST \
      -H 'Content-Type: application/json' \
      -d '{"username":"itadmin","password":"Admin@2024"}' -o /dev/null 2>/dev/null; then
      echo " ✅"
      break
    fi
    sleep 1
    echo -n "."
    if [[ $i -eq 40 ]]; then
      echo " ❌ 超时"
      kill "${BACKEND_PID}" 2>/dev/null || true
      exit 1
    fi
  done

  start_frontend_docker

  # 等待前端就绪（最多 90s，Docker 冷启动 + next dev 编译较慢）
  echo -n "   等待前端就绪..."
  for i in $(seq 1 90); do
    if curl -sf "http://localhost:${E2E_FRONTEND_PORT}" -o /dev/null 2>/dev/null; then
      echo " ✅"
      break
    fi
    sleep 1
    echo -n "."
    if [[ $i -eq 90 ]]; then
      echo " ❌ 超时"
      kill "${BACKEND_PID}" 2>/dev/null || true
      stop_frontend_docker
      exit 1
    fi
  done

  # PID 文件中记录后端 PID + 容器名（stop 脚本会处理）
  echo "${BACKEND_PID} docker:${E2E_FRONTEND_CONTAINER}" > "${PID_FILE}"
  echo ""
  echo "✅ E2E 测试栈已启动（后台）"
  echo "   后端日志: /tmp/e2e-backend.log"
  echo "   前端日志: docker logs ${E2E_FRONTEND_CONTAINER}"
  echo "   停止: bash testing/scripts/stop-e2e-stack.sh"

else
  # 前台模式：后端 + Docker 前端并行，Ctrl-C 一起停
  trap 'echo ""; echo "🛑 停止 E2E 测试栈..."; kill %1 2>/dev/null; stop_frontend_docker; exit 0' INT TERM

  start_backend &
  start_frontend_docker
  echo "📺 前端日志: docker logs -f ${E2E_FRONTEND_CONTAINER}"
  wait
fi
