#!/bin/bash
# ═══════════════════════════════════════════════════════════════════
# SciLit — 生产环境一键部署脚本
# ═══════════════════════════════════════════════════════════════════
#
# 用法:
#   export SCILIT_HOST=your-server.com
#   ./deploy.sh                        # 部署到默认服务器
#   ./deploy.sh --skip-tests           # 跳过本地测试，直接部署
#   ./deploy.sh --help                 # 查看全部选项
#
# 前置条件:
#   - 本地: SSH 可连接到服务器（推荐用 ~/.ssh/config）
#   - 服务器: 已装 Docker + docker compose，已 clone 项目
#   - 服务器: .env 文件已配置好
#   - 代码仓库: 支持 Gitee / GitHub / 自建 Git（git pull 能工作即可）
#
# 远程仓库配置:
#   - 本地 git remote 指向 Gitee:
#     git remote add gitee https://gitee.com/你的用户名/scilit-oncology.git
#     # deploy.sh 会尝试 push 到 origin（可设为 Gitee）
#   - 服务器上 git remote 也指向 Gitee:
#     git remote set-url origin https://gitee.com/你的用户名/scilit-oncology.git
#   - 可选: GitHub 同时保留用作备份:
#     git remote add github https://github.com/你的用户名/scilit-oncology.git
# ═══════════════════════════════════════════════════════════════════

set -euo pipefail

# ── 默认配置 ─────────────────────────────────────────────────────
# 改为你的服务器信息
SERVER_HOST="${SCILIT_HOST:-your-server.com}"
SERVER_USER="${SCILIT_USER:-root}"
SERVER_PATH="${SCILIT_PATH:-/root/scilit-oncology}"

# 本地项目根目录
LOCAL_ROOT="$(cd "$(dirname "$0")" && pwd)"

# ── 颜色 ─────────────────────────────────────────────────────────
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color

info()  { echo -e "${GREEN}[✓]${NC} $1"; }
warn()  { echo -e "${YELLOW}[!]${NC} $1"; }
error() { echo -e "${RED}[✗]${NC} $1"; exit 1; }

# ── 参数解析 ─────────────────────────────────────────────────────
SKIP_TESTS=false
ENV_FILE=""

while [[ $# -gt 0 ]]; do
  case "$1" in
    --skip-tests) SKIP_TESTS=true; shift ;;
    --env) ENV_FILE="$2"; shift 2 ;;
    --help)
      echo "用法: $0 [--skip-tests] [--env .env.prod]"
      echo ""
      echo "  --skip-tests     跳过本地测试和 lint"
      echo "  --env FILE        指定服务器上的 .env 文件路径（默认: {SERVER_PATH}/.env）"
      exit 0 ;;
    *) error "未知参数: $1，使用 --help 查看用法" ;;
  esac
done

# ── 第一步：本地检查 + 测试 ─────────────────────────────────────
echo "════════════════════════════════════════════"
echo "  SciLit 部署"
echo "  目标: ${SERVER_USER}@${SERVER_HOST}"
echo "════════════════════════════════════════════"
echo ""

if [ "$SKIP_TESTS" = false ]; then
  echo "── 1/4 本地测试 ──"
  cd "$LOCAL_ROOT/backend"
  info "运行后端测试..."
  python -m pytest tests/ -v --no-cov --tb=short 2>&1 | tail -5
  local EXIT_CODE=$?
  if [ $EXIT_CODE -ne 0 ]; then
    error "后端测试失败（exit code $EXIT_CODE），中止部署。用 --skip-tests 跳过。"
  fi
  info "后端测试通过"

  cd "$LOCAL_ROOT/frontend"
  info "构建前端（验证）..."
  npm run build 2>&1 | tail -3
  info "前端构建通过"
  cd "$LOCAL_ROOT"
else
  echo "── 1/4 本地测试 ──  已跳过"
fi

# ── 第二步：推送代码 ─────────────────────────────────────────────
echo ""
echo "── 2/4 推送代码 ──"
cd "$LOCAL_ROOT"
if git status --porcelain | grep -q .; then
  warn "有未提交的改动，建议先提交再部署。继续？(y/N)"
  read -r yn
  if [ "$yn" != "y" ] && [ "$yn" != "Y" ]; then
    error "已取消"
  fi
fi

# 尝试推送到 GitHub（失败不阻塞）
if git push origin main 2>&1; then
  info "GitHub push 成功"
else
  warn "GitHub push 失败（网络问题），继续部署..."
fi

# ── 第三步：服务器拉取 + 构建 + 启动 ────────────────────────────
echo ""
echo "── 3/4 服务器部署 ──"

DEPLOY_CMD=$(cat << SSHCMD
set -e
cd ${SERVER_PATH}

echo "  拉取代码..."
git pull origin main 2>&1 || echo "  [!] git pull 失败，继续用本地代码"

echo "  构建并启动..."
docker compose -f docker-compose.prod.yml build 2>&1 | tail -3

# 优雅重启（不中断现有连接）
echo "  正在更新服务..."
docker compose -f docker-compose.prod.yml up -d --no-deps --remove-orphans 2>&1

echo "  等待就绪..."
sleep 5
curl -sf http://localhost:8000/health && echo "  [✓] backend 健康检查通过" || echo "  [!] backend 健康检查失败"
curl -sf http://localhost:80 && echo "  [✓] frontend 健康检查通过" || echo "  [!] frontend 健康检查失败"

echo "  清理旧镜像..."
docker image prune -f 2>&1 | tail -1
SSHCMD
)

ssh -o StrictHostKeyChecking=no "${SERVER_USER}@${SERVER_HOST}" bash <<< "$DEPLOY_CMD"

info "服务器部署完成"

# ── 第四步：日志 ─────────────────────────────────────────────────
echo ""
echo "── 4/4 查看日志 ──"
echo ""
echo "  实时日志: ssh ${SERVER_USER}@${SERVER_HOST} 'cd ${SERVER_PATH} && docker compose -f docker-compose.prod.yml logs -f'"
echo "  backend:  ssh ${SERVER_USER}@${SERVER_HOST} 'cd ${SERVER_PATH} && docker compose -f docker-compose.prod.yml logs -f backend'"
echo "  重新部署: cd $(pwd) && bash deploy.sh"
echo ""
info "部署完毕 🎉"
