#!/usr/bin/env bash
# cutover.sh —— 一次性切换:宿主 nginx → pangolin-edge 容器(需 root 一次)。
#   sudo bash /home/ec2-user/pangolin/scripts/cutover.sh
# 选空闲时段执行;代理(Marzban REALITY)会有秒级重连,Shadowrocket 自动恢复。
# 失败可秒级回滚:docker-compose -p pangolin stop edge && systemctl start nginx
set -euo pipefail

if [[ "$(id -u)" -ne 0 ]]; then
  echo "请以 root 运行:sudo bash $0" >&2
  exit 1
fi

cd "$(dirname "$0")/.."   # -> deploy/
EDGE_IMAGE="nginx:1.27-alpine"

echo "==> [1/4] 切换前校验 edge 配置(含证书路径)"
docker run --rm \
  -v "$PWD/edge/nginx.conf:/etc/nginx/nginx.conf:ro" \
  -v "$PWD/edge/stream.conf:/etc/nginx/stream.conf:ro" \
  -v "$PWD/edge/conf.d:/etc/nginx/conf.d:ro" \
  -v /etc/letsencrypt:/etc/letsencrypt:ro \
  -v /opt/jiu:/opt/jiu:ro \
  -v /var/www/pay:/var/www/pay:ro \
  "$EDGE_IMAGE" nginx -t

rollback() {
  echo "==> !! 自动回滚:停 edge,恢复宿主 nginx" >&2
  docker-compose -p pangolin stop edge >/dev/null 2>&1 || true
  systemctl enable nginx >/dev/null 2>&1 || true
  systemctl start nginx || echo "    !! 宿主 nginx 启动失败,请手动 systemctl start nginx" >&2
  echo "    已回滚到宿主 nginx。" >&2
  exit 1
}

echo "==> [2/4] 停用宿主 nginx 并起 edge 容器(交接窗口,秒级)"
systemctl stop nginx
systemctl disable nginx 2>/dev/null || true
docker build -t pangolin-edge:local ./edge || { echo "    edge 镜像构建失败" >&2; rollback; }
if ! docker-compose -p pangolin up -d edge singbox; then
  echo "    edge 启动失败" >&2; rollback
fi

echo "==> [3/4] 等待并健康检查"
sleep 2
# edge 容器必须在跑
if [[ "$(docker inspect -f '{{.State.Running}}' pangolin-edge 2>/dev/null)" != "true" ]]; then
  echo "    edge 容器未运行" >&2; docker logs pangolin-edge 2>&1 | tail -10; rollback
fi
fail=0
# REALITY 经 443 → 10443(Marzban),SNI=www.cloudflare.com 应握手成功
if echo | timeout 10 openssl s_client -connect 127.0.0.1:443 -servername www.cloudflare.com >/dev/null 2>&1; then
  echo "    [REALITY] 443 握手 OK"; else echo "    [REALITY] 握手失败"; fail=1; fi
# 业务 vhost(经 stream→本机 8443/8444/8445)
for d in blog jiu vpn; do
  code="$(curl -ks -o /dev/null -w '%{http_code}' --resolve ${d}.51yanmei.com:443:127.0.0.1 https://${d}.51yanmei.com/ 2>/dev/null || echo 000)"
  echo "    [${d}] https -> ${code}"
  [[ "$code" =~ ^[2-4][0-9][0-9]$ ]] || fail=1
done

echo "==> [4/4] 结果"
if [[ "$fail" == "0" ]]; then
  echo "    切换成功 ✅(宿主 nginx 已停,配置保留可回滚)"
else
  echo "    部分检查未通过" >&2; rollback
fi
