name: '📚 光湖智库 · guanghu.online 部署'

# ═══════════════════════════════════════════════════════════
# 光湖智库节点独立部署工作流
# 项目编号: ZY-PROJ-006
# 域名:     guanghu.online
# 服务器:   ZY-SVR-006 (43.153.203.105 · 新加坡)
# 守护:     铸渊 · ICE-GL-ZY001
# 版权:     国作登字-2026-A-00037559
#
# 功能:
#   1. deploy     — 部署前端 + 后端 + Nginx + PM2
#   2. setup-ssl  — 申请/续签 SSL 证书
#   3. health     — 检查 API + 前端运行状态
#   4. rollback   — 回滚到上一份配置
#
# 所需 GitHub Secrets:
#   ZY_NOVEL_HOST       — ZY-SVR-006 IP (43.153.203.105)
#   ZY_NOVEL_KEY        — ZY-SVR-006 SSH 私钥
#   ZY_NOVEL_USER       — ZY-SVR-006 SSH 用户名 (root)
#   ZY_NOVEL_JWT_SECRET — JWT 签名密钥
#   ZY_OSS_KEY          — 腾讯云 COS SecretId（仓库已有·映射为 ZY_COS_SECRET_ID）
#   ZY_OSS_SECRET       — 腾讯云 COS SecretKey（仓库已有·映射为 ZY_COS_SECRET_KEY）
#   ZY_NOVEL_COS_BUCKET — COS 桶名（仓库已有·映射为 ZY_COS_BUCKET）
#   （ZY_COS_REGION 不使用 Secret · 硬编码 ap-singapore · 避免覆盖广州桶配置）
#   ZY_ZHIKU_DOMAIN     — 域名 (guanghu.online)
#   ZY_SMTP_USER        — SMTP 发件邮箱 (如 565183519@qq.com)
#   ZY_SMTP_PASS        — SMTP 应用专用密码 (非邮箱登录密码)
#   ZY_DEEPSEEK_API_KEY — DeepSeek LLM API 密钥 (Agent对话)
# ═══════════════════════════════════════════════════════════

on:
  push:
    branches: [main]
    paths:
      - 'server/zhiku-node/**'
      - 'server/nginx/zhiku-guanghu-online.conf'
  workflow_dispatch:
    inputs:
      action:
        description: '执行动作'
        required: true
        default: 'deploy'
        type: choice
        options:
          - deploy
          - setup-datasources
          - setup-ssl
          - health
          - rollback

jobs:

  # ═══════════════════════════════════════════════════════
  # Job 1: 完整部署
  # ═══════════════════════════════════════════════════════
  deploy:
    name: '🚀 智库节点部署 · guanghu.online'
    runs-on: ubuntu-latest
    permissions:
      contents: read
    if: |
      github.event_name == 'push' ||
      (github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'deploy')

    steps:
      - name: '📥 检出代码'
        uses: actions/checkout@v4

      - name: '🔑 配置 SSH'
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.ZY_NOVEL_KEY }}" > ~/.ssh/zhiku_key
          chmod 600 ~/.ssh/zhiku_key
          ssh-keyscan -H ${{ secrets.ZY_NOVEL_HOST }} >> ~/.ssh/known_hosts

      - name: '📦 安装服务器基础依赖'
        run: |
          ssh -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }} << 'ENDSSH'
          set -e
          
          # 安装 Node.js 20 (如果还没有)
          if ! command -v node &>/dev/null || [ "$(node -v | cut -d. -f1 | tr -d v)" -lt 20 ]; then
            curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
            apt-get install -y nodejs
          fi
          
          # 安装 PM2
          npm list -g pm2 &>/dev/null || npm install -g pm2
          
          # 创建目录结构
          mkdir -p /opt/zhiku/public/assets/{css,js,img}
          mkdir -p /opt/zhiku/public/modules
          mkdir -p /opt/zhiku/server
          mkdir -p /opt/zhiku/data/index
          mkdir -p /opt/zhiku/data/books
          mkdir -p /opt/zhiku/data/guardian
          mkdir -p /opt/zhiku/datasources/fqweb
          mkdir -p /opt/zhiku/datasources/swiftcat
          mkdir -p /var/log/zhiku
          mkdir -p /var/www/certbot
          
          echo "[ZY-SVR-006] 基础目录已就绪"
          ENDSSH

      - name: '📤 上传前端文件'
        run: |
          scp -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no -r \
            server/zhiku-node/public/* \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }}:/opt/zhiku/public/

      - name: '📤 上传后端文件'
        run: |
          scp -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no -r \
            server/zhiku-node/server/package.json \
            server/zhiku-node/server/package-lock.json \
            server/zhiku-node/server/server.js \
            server/zhiku-node/server/.env.example \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }}:/opt/zhiku/server/

      - name: '📤 上传镜面 Agent + 镜防模块 + 书岚 Agent + 内置数据源'
        run: |
          # 创建远程目录（含铸渊哨兵 + 永久记忆存储）
          ssh -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }} \
            'mkdir -p /opt/zhiku/server/mirror-agent/data/{snapshots,tickets,memory} /opt/zhiku/server/mirror-shield /opt/zhiku/server/shulan-agent /opt/zhiku/server/builtin-source /opt/zhiku/server/zhuyuan-sentinel /opt/zhiku/data/guardian /opt/zhiku/data/sentinel'
          
          # 上传 mirror-agent
          scp -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no -r \
            server/zhiku-node/server/mirror-agent/*.js \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }}:/opt/zhiku/server/mirror-agent/
          
          # 上传 mirror-shield
          scp -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no -r \
            server/zhiku-node/server/mirror-shield/*.js \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }}:/opt/zhiku/server/mirror-shield/
          
          # 上传 shulan-agent（书岚人格体系统）
          scp -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no -r \
            server/zhiku-node/server/shulan-agent/*.js \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }}:/opt/zhiku/server/shulan-agent/
          
          # 上传 builtin-source（内置数据源直连 · 搜索下载fallback）
          scp -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no -r \
            server/zhiku-node/server/builtin-source/*.js \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }}:/opt/zhiku/server/builtin-source/
          
          # 上传 zhuyuan-sentinel（铸渊哨兵 · 永久记忆 + 书源自动运维）
          scp -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no -r \
            server/zhiku-node/server/zhuyuan-sentinel/*.js \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }}:/opt/zhiku/server/zhuyuan-sentinel/

      - name: '📤 上传 PM2 配置'
        run: |
          scp -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no \
            server/zhiku-node/ecosystem.config.js \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }}:/opt/zhiku/

      - name: '📤 上传 Nginx 配置'
        run: |
          scp -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no \
            server/nginx/zhiku-guanghu-online.conf \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }}:/etc/nginx/sites-available/zhiku

      - name: '⚙️ 配置环境变量 + 安装依赖 + 启动服务'
        run: |
          ssh -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }} << 'ENDSSH'
          set -e
          
          # ─── 写入 .env ───
          cat > /opt/zhiku/server/.env << 'ENVEOF'
          PORT=3006
          NODE_ENV=production
          ZY_ZHIKU_JWT_SECRET=${{ secrets.ZY_NOVEL_JWT_SECRET }}
          ZY_ZHIKU_TOKEN_TTL=86400
          ZY_COS_SECRET_ID=${{ secrets.ZY_OSS_KEY }}
          ZY_COS_SECRET_KEY=${{ secrets.ZY_OSS_SECRET }}
          ZY_COS_BUCKET=${{ secrets.ZY_NOVEL_COS_BUCKET }}
          ZY_COS_REGION=ap-singapore
          ZY_ZHIKU_DATA_DIR=/opt/zhiku/data
          ZY_ZHIKU_LOG_DIR=/var/log/zhiku
          ZY_ZHIKU_DOMAIN=${{ secrets.ZY_ZHIKU_DOMAIN }}
          ZY_FANQIE_API_URL=http://127.0.0.1:9999
          ZY_QIMAO_API_URL=http://127.0.0.1:7700
          ZY_SMTP_PORT=465
          ZY_SMTP_USER=${{ secrets.ZY_SMTP_USER }}
          ZY_SMTP_PASS=${{ secrets.ZY_SMTP_PASS }}
          ZY_DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions
          ZY_DEEPSEEK_API_KEY=${{ secrets.ZY_DEEPSEEK_API_KEY }}
          ENVEOF
          
          # 去除可能的前导空格
          sed -i 's/^[[:space:]]*//' /opt/zhiku/server/.env
          
          # ─── 安装 Node.js 依赖 ───
          cd /opt/zhiku/server
          npm install --production 2>&1 | tail -5
          
          # ─── Nginx 配置 ───
          ln -sf /etc/nginx/sites-available/zhiku /etc/nginx/sites-enabled/zhiku
          
          # ─── 启动服务 ───
          cd /opt/zhiku
          pm2 start ecosystem.config.js
          pm2 save
          
          # ─── 安装 COS CLI 工具 ───
          if ! command -v coscli &>/dev/null; then
            wget https://github.com/tencentyun/coscli/releases/download/v0.11.0-beta/coscli-linux
            chmod +x coscli-linux
            mv coscli-linux /usr/local/bin/coscli
          fi
          
          # ─── 配置 COS CLI ───
          mkdir -p ~/.cos.yaml
          cat > ~/.cos.yaml << 'COSEOF'
          configs:
            default:
              secretid: $ZY_COS_SECRET_ID
              secretkey: $ZY_COS_SECRET_KEY
              region: $ZY_COS_REGION
              bucket: $ZY_COS_BUCKET
          COSEOF
          
          # ─── 上传备份脚本 ───
          mkdir -p /opt/zhiku/scripts
          
          # ─── 设置定时备份任务 ───
          (crontab -l 2>/dev/null; echo "0 4 * * * /opt/zhiku/scripts/backup-data-to-cos.sh >> /var/log/zhiku/backup.log 2>&1") | crontab -
          
          # ─── 重启 cron 服务 ───
          systemctl restart cron
          
          echo "[ZY-SVR-006] 服务启动完成"
          ENDSSH

      - name: '📤 上传备份脚本'
        run: |
          scp -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no \
            server/zhiku-node/scripts/backup-data-to-cos.sh \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }}:/opt/zhiku/scripts/
          
          ssh -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }} \
            'chmod +x /opt/zhiku/scripts/backup-data-to-cos.sh'

      - name: '✅ 验证服务状态'
        run: |
          ssh -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }} << 'ENDSSH'
          set -e
          
          # 检查 PM2 状态
          if ! pm2 list | grep -q "online"; then
            echo "[ERROR] PM2 服务未正常运行"
            exit 1
          fi
          
          # 检查 API 健康状态
          API_HEALTH=$(curl -s http://localhost:3006/api/health | jq -r '.status')
          if [ "$API_HEALTH" != "running" ]; then
            echo "[ERROR] API 健康检查失败: $API_HEALTH"
            exit 1
          fi
          
          # 检查备份脚本
          if [ ! -x "/opt/zhiku/scripts/backup-data-to-cos.sh" ]; then
            echo "[ERROR] 备份脚本未正确安装"
            exit 1
          fi
          
          # 检查定时任务
          if ! crontab -l | grep -q "backup-data-to-cos"; then
            echo "[ERROR] 定时备份任务未设置"
            exit 1
          fi
          
          echo "[ZY-SVR-006] 所有服务验证通过"
          ENDSSH

  # ═══════════════════════════════════════════════════════
  # Job 2: 申请 SSL 证书
  # ═══════════════════════════════════════════════════════
  setup-ssl:
    name: '🔒 申请 SSL 证书 · guanghu.online'
    runs-on: ubuntu-latest
    permissions:
      contents: read
    if: github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'setup-ssl'

    steps:
      - name: '📥 检出代码'
        uses: actions/checkout@v4

      - name: '🔑 配置 SSH'
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.ZY_NOVEL_KEY }}" > ~/.ssh/zhiku_key
          chmod 600 ~/.ssh/zhiku_key
          ssh-keyscan -H ${{ secrets.ZY_NOVEL_HOST }} >> ~/.ssh/known_hosts

      - name: '📦 安装 certbot'
        run: |
          ssh -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }} << 'ENDSSH'
          set -e
          
          # 安装 certbot
          apt-get update
          apt-get install -y certbot python3-certbot-nginx
          
          # 申请证书 (webroot 模式)
          certbot certonly --webroot -w /var/www/certbot \
            -d ${{ secrets.ZY_ZHIKU_DOMAIN }} \
            -d www.${{ secrets.ZY_ZHIKU_DOMAIN }} \
            --non-interactive \
            --agree-tos \
            --email ${{ secrets.ZY_SMTP_USER }} \
            --expand
          
          # 设置自动续期
          (crontab -l 2>/dev/null; echo "0 3 * * * certbot renew --quiet --post-hook 'systemctl reload nginx'" ) | crontab -
          
          # 重启 Nginx
          systemctl reload nginx
          
          echo "[ZY-SVR-006] SSL 证书申请完成"
          ENDSSH

  # ═══════════════════════════════════════════════════════
  # Job 3: 健康检查
  # ═══════════════════════════════════════════════════════
  health:
    name: '🩺 健康检查 · guanghu.online'
    runs-on: ubuntu-latest
    permissions:
      contents: read
    if: github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'health'

    steps:
      - name: '📥 检出代码'
        uses: actions/checkout@v4

      - name: '🔑 配置 SSH'
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.ZY_NOVEL_KEY }}" > ~/.ssh/zhiku_key
          chmod 600 ~/.ssh/zhiku_key
          ssh-keyscan -H ${{ secrets.ZY_NOVEL_HOST }} >> ~/.ssh/known_hosts

      - name: '🔄 检查服务状态'
        run: |
          ssh -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }} << 'ENDSSH'
          set -e
          
          # 检查 PM2
          echo "=== PM2 状态 ==="
          pm2 list
          
          # 检查 API 健康
          echo "\n=== API 健康状态 ==="
          curl -s http://localhost:3006/api/health | jq
          
          # 检查 Nginx
          echo "\n=== Nginx 状态 ==="
          systemctl status nginx --no-pager
          
          # 检查备份日志
          echo "\n=== 最近备份日志 ==="
          tail -n 20 /var/log/zhiku/backup.log 2>/dev/null || echo "无备份日志"
          
          # 检查定时任务
          echo "\n=== 定时任务 ==="
          crontab -l
          
          echo "[ZY-SVR-006] 健康检查完成"
          ENDSSH

  # ═══════════════════════════════════════════════════════
  # Job 4: 回滚
  # ═══════════════════════════════════════════════════════
  rollback:
    name: '⏪ 回滚到上一版本 · guanghu.online'
    runs-on: ubuntu-latest
    permissions:
      contents: read
    if: github.event_name == 'workflow_dispatch' && github.event.inputs.action == 'rollback'

    steps:
      - name: '📥 检出代码'
        uses: actions/checkout@v4

      - name: '🔑 配置 SSH'
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.ZY_NOVEL_KEY }}" > ~/.ssh/zhiku_key
          chmod 600 ~/.ssh/zhiku_key
          ssh-keyscan -H ${{ secrets.ZY_NOVEL_HOST }} >> ~/.ssh/known_hosts

      - name: '⏪ 执行回滚'
        run: |
          ssh -i ~/.ssh/zhiku_key -o StrictHostKeyChecking=no \
            ${{ secrets.ZY_NOVEL_USER }}@${{ secrets.ZY_NOVEL_HOST }} << 'ENDSSH'
          set -e
          
          # 回滚 PM2
          cd /opt/zhiku
          pm2 restart ecosystem.config.js
          
          echo "[ZY-SVR-006] 回滚完成"
          ENDSSH