name: chaos / restore drill

# M3 of chaos engineering: 每周在 GHA runner（全新 Ubuntu 环境）独立
# 从 OSS 拉备份 + restore + 验证，模拟"真·灾难场景 epsilon 挂了异地恢复"。
# 设计见 brain/issues/005-chaos-engineering-backup-migration.md

on:
  schedule:
    - cron: "0 4 * * 0"   # UTC 每周日 04:00（= 北京 12:00）
  workflow_dispatch:

jobs:
  drill:
    name: 异地 restore 演练（GHA runner）
    runs-on: ubuntu-latest
    steps:
      - name: 装 aliyun cli
        run: |
          ARCH=$(uname -m | sed s/x86_64/amd64/ | sed s/aarch64/arm64/)
          cd /tmp
          curl -fsSL "https://aliyuncli.alicdn.com/aliyun-cli-linux-latest-${ARCH}.tgz" -o aliyun-cli.tgz
          tar xzf aliyun-cli.tgz
          sudo mv aliyun /usr/local/bin/
          aliyun --version

      - name: 装 sqlite3
        run: sudo apt-get install -y -qq sqlite3

      - name: 配 aliyun profile（临时）
        env:
          AK_ID: ${{ secrets.ALIYUN_OSS_AK_ID }}
          AK_SECRET: ${{ secrets.ALIYUN_OSS_AK_SECRET }}
        run: |
          aliyun configure set \
            --profile drill \
            --mode AK \
            --access-key-id "$AK_ID" \
            --access-key-secret "$AK_SECRET" \
            --region cn-hangzhou

      - name: 拉最新备份 + 完整 restore 演练
        run: |
          set -euo pipefail

          BUCKET="agentaily-backup-xiangqin-prod"
          ENDPOINT="oss-cn-hangzhou.aliyuncs.com"
          TS=$(date +%Y%m%d%H%M%S)
          TMP_DIR="/tmp/drill-${TS}"
          mkdir -p "$TMP_DIR"

          # 1. 找最新备份
          LATEST=$(aliyun --profile drill oss ls "oss://${BUCKET}/daily/" -e "$ENDPOINT" \
              | grep -oE 'xiangqin-[0-9]{8}\.db\.gz' | sort -u | tail -1)
          if [ -z "$LATEST" ]; then
              echo "::error::OSS 没有备份"
              exit 1
          fi
          echo "最新备份: $LATEST"

          # 2. 下载到 GHA runner
          aliyun --profile drill oss cp "oss://${BUCKET}/daily/${LATEST}" "${TMP_DIR}/${LATEST}" \
              -e "$ENDPOINT" --force
          ls -la "${TMP_DIR}/"

          # 3. gunzip
          gunzip "${TMP_DIR}/${LATEST}"
          DB_FILE="${TMP_DIR}/${LATEST%.gz}"

          # 4. sqlite integrity
          INTEGRITY=$(sqlite3 "$DB_FILE" 'PRAGMA integrity_check' | head -1)
          echo "integrity: $INTEGRITY"
          [ "$INTEGRITY" = "ok" ] || { echo "::error::integrity failed: $INTEGRITY"; exit 1; }

          # 5. 核心表 schema 验证
          REQUIRED="users sessions auth_requests profiles"
          for t in $REQUIRED; do
              exists=$(sqlite3 "$DB_FILE" "SELECT name FROM sqlite_master WHERE type='table' AND name='$t'")
              if [ -z "$exists" ]; then
                  echo "::error::核心表缺失: $t"
                  exit 1
              fi
          done

          # 6. 核心表行数（基线）
          USERS=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM users")
          TABLES=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM sqlite_master WHERE type='table'")
          SIZE=$(du -b "$DB_FILE" | cut -f1)

          echo "✓ 异地 restore 通过: users=$USERS / tables=$TABLES / size=${SIZE}B"

          # 7. 写 summary
          cat <<EOF >> "$GITHUB_STEP_SUMMARY"
          ### Restore drill（GHA runner 异地演练）

          - 备份文件: \`$LATEST\`
          - 大小: ${SIZE} B
          - integrity_check: **$INTEGRITY**
          - users 行数: $USERS
          - 总表数: $TABLES
          - 核心表存在（users / sessions / auth_requests / profiles）: ✓
          - 结论: ✅ **异地 restore 链路健康**

          模拟场景: 假设 epsilon 整机 loss，GHA runner 作为全新环境能否从 OSS 恢复数据库并读取。
          EOF
