#!/bin/sh
set -eu

# ============================================
# Staging 部署脚本 - Registry 方式
# 用法：IMAGE_TAG=<sha|version> REGISTRY_TOKEN=<token> sh deploy-staging.sh
# ============================================

IMAGE_TAG="${IMAGE_TAG:-}"
REGISTRY="${REGISTRY:-git.xiaoxiajianji.com/xiaoxia/xiaoxia-saas}"
REGISTRY_USER="${REGISTRY_USER:-xiaoxia}"
REGISTRY_TOKEN="${REGISTRY_TOKEN:-}"

ENV_FILE="${ENV_FILE:-/var/lib/xiaoxia-saas-staging/.env}"
COMPOSE_DIR="${COMPOSE_DIR:-/var/lib/xiaoxia-saas-staging/repo/infra/docker}"
GENERATED_DIR="${GENERATED_DIR:-/var/lib/xiaoxia-saas-staging/generated}"

if [ -z "$IMAGE_TAG" ]; then
  echo "ERROR: IMAGE_TAG is required"
  exit 1
fi

test -f "$ENV_FILE"
mkdir -p "$GENERATED_DIR"

# ---- 登录 Registry ----
if [ -n "$REGISTRY_TOKEN" ]; then
  echo "Logging in to registry: $REGISTRY"
  printf %s "$REGISTRY_TOKEN" | docker login "$(echo $REGISTRY | cut -d/ -f1)" -u "$REGISTRY_USER" --password-stdin 2>/dev/null || {
    echo "WARN: docker login failed, will try to pull anyway"
  }
fi

# ---- Pull 三镜像 ----
REGISTRY_API="${REGISTRY}/xiaoxia-saas-api:${IMAGE_TAG}"
REGISTRY_WORKER="${REGISTRY}/xiaoxia-saas-worker:${IMAGE_TAG}"
REGISTRY_WEB="${REGISTRY}/xiaoxia-saas-web:${IMAGE_TAG}"

LOCAL_API="${REGISTRY}/xiaoxia-saas-api:staging"
LOCAL_WORKER="${REGISTRY}/xiaoxia-saas-worker:staging"
LOCAL_WEB="${REGISTRY}/xiaoxia-saas-web:staging"

echo "Pulling API image..."
docker pull "$REGISTRY_API"
echo "Pulling Worker image..."
docker pull "$REGISTRY_WORKER"
echo "Pulling Web image..."
docker pull "$REGISTRY_WEB"

# ---- Re-tag 成本地名 ----
docker tag "$REGISTRY_API" "$LOCAL_API"
docker tag "$REGISTRY_WORKER" "$LOCAL_WORKER"
docker tag "$REGISTRY_WEB" "$LOCAL_WEB"
echo "All images pulled and tagged."

# ---- 确保基础设施容器在运行 ----
for c in xiaoxia-postgres-staging xiaoxia-redis-staging; do
  if ! docker inspect "$c" >/dev/null 2>&1; then
    echo "ERROR: Required container not found: $c"
    exit 1
  fi
  state=$(docker inspect -f {{.State.Status}} "$c")
  if [ "$state" != "running" ]; then
    echo "ERROR: Container not running: $c ($state)"
    exit 1
  fi
done

# ---- 确保 staging 网络存在 ----
docker network create xiaoxia-net-staging 2>/dev/null || true

# ---- 执行数据库 Migration ----
echo "Running database migrations..."
docker run --rm --env-file "$ENV_FILE" --network xiaoxia-net-staging "$LOCAL_API" sh -c "cd /app && alembic upgrade head"
echo "Migrations completed."

# ---- 停止旧容器 ----
docker rm -f xiaoxia-api-staging 2>/dev/null || true
docker rm -f xiaoxia-worker-staging 2>/dev/null || true
docker rm -f xiaoxia-web-staging 2>/dev/null || true

# ---- 启动 API ----
echo "Starting API container..."
docker run -d \
  --name xiaoxia-api-staging \
  --env-file "$ENV_FILE" \
  --network xiaoxia-net-staging \
  -p 127.0.0.1:8000:8000 \
  -e APP_ENV=staging \
  -e APP_VERSION="$IMAGE_TAG" \
  -e GENERATED_FILES_DIR=/app/generated \
  -e GENERATED_FILES_URL_PREFIX=/generated-files \
  -v "$GENERATED_DIR:/app/generated" \
  --restart unless-stopped \
  --label com.centurylinklabs.watchtower.enable=true \
  --health-cmd "python -c \"import urllib.request; urllib.request.urlopen('http://localhost:8000/health', timeout=5)\"" \
  --health-interval 30s \
  --health-timeout 10s \
  --health-retries 3 \
  --health-start-period 40s \
  "$LOCAL_API"

# ---- 启动 Worker ----
echo "Starting Worker container..."
docker run -d \
  --name xiaoxia-worker-staging \
  --env-file "$ENV_FILE" \
  --network xiaoxia-net-staging \
  -e APP_ENV=staging \
  -e APP_VERSION="$IMAGE_TAG" \
  -e WORKER_CONCURRENCY=1 \
  -e WORKER_MAX_TASKS_PER_CHILD=100 \
  -e GENERATED_FILES_DIR=/app/generated \
  -e GENERATED_FILES_URL_PREFIX=/generated-files \
  -v "$GENERATED_DIR:/app/generated" \
  --restart unless-stopped \
  --label com.centurylinklabs.watchtower.enable=true \
  --health-cmd "sh -c \"grep -q celery /proc/1/cmdline || exit 1\"" \
  --health-interval 30s \
  --health-timeout 10s \
  --health-retries 3 \
  --health-start-period 30s \
  "$LOCAL_WORKER"

# ---- 启动 Web ----
# Web 镜像默认打包 production nginx.conf，staging 需要挂载 staging 配置
NGINX_CONF="${NGINX_CONF:-${COMPOSE_DIR}/nginx-staging.conf}"
if [ ! -f "$NGINX_CONF" ]; then
  echo "WARN: nginx config not found at $NGINX_CONF, using image default"
  NGINX_VOLUME=""
else
  NGINX_VOLUME="-v ${NGINX_CONF}:/etc/nginx/conf.d/default.conf:ro"
fi

echo "Starting Web container..."
docker run -d \
  --name xiaoxia-web-staging \
  --network xiaoxia-net-staging \
  -p 127.0.0.1:3001:80 \
  --restart unless-stopped \
  --label com.centurylinklabs.watchtower.enable=true \
  $NGINX_VOLUME \
  --health-cmd "wget --spider -q http://127.0.0.1:80" \
  --health-interval 30s \
  --health-timeout 5s \
  --health-retries 3 \
  "$LOCAL_WEB"

# ---- 等待 API 健康 ----
echo "Waiting for API to become healthy..."
i=0
while [ "$i" -lt 30 ]; do
  if curl -sf --max-time 5 http://127.0.0.1:8000/health >/dev/null 2>&1; then
    echo "API is healthy!"
    break
  fi
  i=$((i + 1))
  echo "  Waiting... ($i/30)"
  sleep 2
done

if [ "$i" -ge 30 ]; then
  echo "ERROR: API did not become healthy within 60s"
  docker logs --tail 30 xiaoxia-api-staging
  exit 1
fi

# ---- 清理旧镜像 ----
docker image prune -af --filter "until=72h" 2>/dev/null || true

echo ""
echo "=== Staging deployment complete ==="
echo "API:      http://127.0.0.1:8000"
echo "Web:      http://127.0.0.1:3001"
echo "Version:  $IMAGE_TAG"
docker ps --format "table {{.Names}}\t{{.Status}}" | grep staging

# Watchtower auto-update: 容器加com.centurylinklabs.watchtower.enable=true标签，用:staging tag启动
