name: 发布验收测试

on:
  workflow_run:
    workflows:
      - 测试环境部署
    types:
      - completed
    branches:
      - internal
      - main
  workflow_dispatch:

permissions:
  contents: read
  actions: read

concurrency:
  group: release-acceptance
  cancel-in-progress: false

env:
  ACCEPTANCE_ARTIFACT_NAME: release-acceptance-${{ github.run_id }}-${{ github.run_attempt }}
  ACCEPTANCE_REPORT_DIR: acceptance-artifacts
  ACCEPTANCE_REPORT_PATH: acceptance-artifacts/acceptance-report.json
  ACCEPTANCE_TEST_JSON: acceptance-artifacts/go-test.json
  ACCEPTANCE_FAILURE_LOG: acceptance-artifacts/failure.log
  ACCEPTANCE_NODE_SERVER_ID: ${{ vars.ACCEPTANCE_NODE_SERVER_ID || '31' }}
  ACCEPTANCE_NODE_PROTOCOL: ${{ vars.ACCEPTANCE_NODE_PROTOCOL || 'trojan' }}

jobs:
  acceptance:
    name: Staging acceptance
    runs-on: ubuntu-latest
    timeout-minutes: 20
    env:
      STAGING_BASE_URL: ${{ secrets.STAGING_BASE_URL || vars.STAGING_BASE_URL || 'https://tapi.hifast.biz' }}
    if: >-
      ${{
        github.event_name == 'workflow_dispatch' ||
        (
          github.event.workflow_run.conclusion == 'success' &&
          github.event.workflow_run.event == 'push'
        )
      }}

    steps:
      - name: 检出代码
        uses: actions/checkout@v6
        with:
          ref: ${{ github.event.workflow_run.head_sha || github.sha }}

      - name: 配置 Go 环境
        uses: actions/setup-go@v6
        with:
          go-version-file: go.mod
          cache: true

      - name: 准备报告目录
        run: mkdir -p "$ACCEPTANCE_REPORT_DIR"

      - name: 校验必需配置
        env:
          ACCEPTANCE_ADMIN_EMAIL: ${{ secrets.ACCEPTANCE_ADMIN_EMAIL }}
          ACCEPTANCE_ADMIN_PASSWORD: ${{ secrets.ACCEPTANCE_ADMIN_PASSWORD }}
          ACCEPTANCE_USER_EMAIL: ${{ secrets.ACCEPTANCE_USER_EMAIL }}
          ACCEPTANCE_USER_PASSWORD: ${{ secrets.ACCEPTANCE_USER_PASSWORD }}
          STAGING_BASE_URL: ${{ secrets.STAGING_BASE_URL || vars.STAGING_BASE_URL || 'https://tapi.hifast.biz' }}
          STAGING_DB_HOST: ${{ secrets.STAGING_DB_HOST }}
          STAGING_DB_USER: ${{ secrets.STAGING_DB_USER }}
          STAGING_DB_PASSWORD: ${{ secrets.STAGING_DB_PASSWORD }}
          STAGING_DB_NAME: ${{ secrets.STAGING_DB_NAME }}
          STAGING_REDIS_ADDR: ${{ secrets.STAGING_REDIS_ADDR }}
          STAGING_REDIS_PASSWORD: ${{ secrets.STAGING_REDIS_PASSWORD }}
        run: |
          set -euo pipefail

          if [ -z "${STAGING_BASE_URL:-}" ]; then
            echo "STAGING_BASE_URL 未配置且默认值不可用" | tee "$ACCEPTANCE_FAILURE_LOG"
            {
              echo "## 发布验收测试"
              echo
              echo "状态：配置错误"
              echo
              echo "- `STAGING_BASE_URL` 不能为空。"
            } >> "$GITHUB_STEP_SUMMARY"
            exit 1
          fi

          missing_optional=()
          optional=(
            ACCEPTANCE_ADMIN_EMAIL
            ACCEPTANCE_ADMIN_PASSWORD
            ACCEPTANCE_USER_EMAIL
            ACCEPTANCE_USER_PASSWORD
            STAGING_DB_HOST
            STAGING_DB_USER
            STAGING_DB_PASSWORD
            STAGING_DB_NAME
            STAGING_REDIS_ADDR
            STAGING_REDIS_PASSWORD
          )

          for key in "${optional[@]}"; do
            if [ -z "${!key:-}" ]; then
              missing_optional+=("$key")
            fi
          done

          : > "$ACCEPTANCE_FAILURE_LOG"

          if [ "${#missing_optional[@]}" -gt 0 ]; then
            printf '缺少可选 GitHub Actions secrets/vars，部分验收用例将被跳过：\n' | tee -a "$ACCEPTANCE_FAILURE_LOG"
            printf -- '- %s\n' "${missing_optional[@]}" | tee -a "$ACCEPTANCE_FAILURE_LOG"
            {
              echo "## 发布验收测试"
              echo
              echo "状态：部分配置缺失"
              echo
              echo "缺少以下可选 secrets/vars，对应验收用例会在测试阶段自动跳过："
              printf -- '- `%s`\n' "${missing_optional[@]}"
              echo
              echo "- `STAGING_BASE_URL`：${STAGING_BASE_URL}"
            } >> "$GITHUB_STEP_SUMMARY"
          else
            {
              echo "## 发布验收测试"
              echo
              echo "状态：配置检查通过"
              echo
              echo "- `STAGING_BASE_URL`：${STAGING_BASE_URL}"
            } >> "$GITHUB_STEP_SUMMARY"
          fi

      - name: 下载依赖模块
        run: go mod download

      - name: 运行 acceptance 测试
        env:
          ACCEPTANCE_ADMIN_EMAIL: ${{ secrets.ACCEPTANCE_ADMIN_EMAIL }}
          ACCEPTANCE_ADMIN_PASSWORD: ${{ secrets.ACCEPTANCE_ADMIN_PASSWORD }}
          ACCEPTANCE_USER_EMAIL: ${{ secrets.ACCEPTANCE_USER_EMAIL }}
          ACCEPTANCE_USER_PASSWORD: ${{ secrets.ACCEPTANCE_USER_PASSWORD }}
          ACCEPTANCE_NODE_SECRET: ${{ secrets.ACCEPTANCE_NODE_SECRET }}
          ACCEPTANCE_RUN_ID: qa_${{ github.run_id }}_${{ github.run_attempt }}
          STAGING_DB_HOST: ${{ secrets.STAGING_DB_HOST }}
          STAGING_DB_USER: ${{ secrets.STAGING_DB_USER }}
          STAGING_DB_PASSWORD: ${{ secrets.STAGING_DB_PASSWORD }}
          STAGING_DB_NAME: ${{ secrets.STAGING_DB_NAME }}
          STAGING_REDIS_ADDR: ${{ secrets.STAGING_REDIS_ADDR }}
          STAGING_REDIS_PASSWORD: ${{ secrets.STAGING_REDIS_PASSWORD }}
          STAGING_REDIS_DB: ${{ vars.STAGING_REDIS_DB || '0' }}
        run: |
          set -o pipefail

          go test -json ./tests/acceptance/... \
            -staging-url="$STAGING_BASE_URL" \
            -report-path="$ACCEPTANCE_REPORT_PATH" \
            > >(tee "$ACCEPTANCE_TEST_JSON") \
            2> >(tee "$ACCEPTANCE_FAILURE_LOG" >&2)

      - name: 生成测试摘要
        if: always()
        run: |
          set -euo pipefail

          {
            echo "## 发布验收测试"
            echo
            echo "- 状态：${{ job.status }}"
            echo "- Staging URL：${STAGING_BASE_URL}"
            echo "- Artifact：${ACCEPTANCE_ARTIFACT_NAME}"
            echo "- Run URL：${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
            if [ "${{ github.event_name }}" = "workflow_run" ]; then
              echo "- Deploy run：${{ github.event.workflow_run.html_url }}"
              echo "- Deploy SHA：${{ github.event.workflow_run.head_sha }}"
            else
              echo "- 手动触发 SHA：${{ github.sha }}"
            fi
            echo
          } | tee "$ACCEPTANCE_REPORT_DIR/summary.md" >> "$GITHUB_STEP_SUMMARY"

          if [ "${{ job.status }}" = "failure" ]; then
            if [ -s "$ACCEPTANCE_FAILURE_LOG" ]; then
              {
                echo
                echo "Run URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
                echo "Artifact: ${ACCEPTANCE_ARTIFACT_NAME}"
              } >> "$ACCEPTANCE_FAILURE_LOG"
            else
              {
                echo "Acceptance 测试失败。"
                echo "Run URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
                echo "Artifact: ${ACCEPTANCE_ARTIFACT_NAME}"
                echo
                tail -100 "$ACCEPTANCE_TEST_JSON" 2>/dev/null || true
              } > "$ACCEPTANCE_FAILURE_LOG"
            fi
          elif [ ! -f "$ACCEPTANCE_FAILURE_LOG" ]; then
            : > "$ACCEPTANCE_FAILURE_LOG"
          fi

      - name: 上传 acceptance artifact
        if: always()
        uses: actions/upload-artifact@v6
        with:
          name: ${{ env.ACCEPTANCE_ARTIFACT_NAME }}
          path: |
            ${{ env.ACCEPTANCE_REPORT_PATH }}
            ${{ env.ACCEPTANCE_TEST_JSON }}
            ${{ env.ACCEPTANCE_FAILURE_LOG }}
            ${{ env.ACCEPTANCE_REPORT_DIR }}/summary.md
          if-no-files-found: warn
          retention-days: 14

      - name: Telegram 成功通知
        if: success()
        env:
          TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
          TG_CHAT_ID: ${{ secrets.TG_CHAT_ID }}
        run: |
          if [ -z "${TG_BOT_TOKEN:-}" ] || [ -z "${TG_CHAT_ID:-}" ]; then
            echo "Telegram 密钥未配置，跳过通知。"
            exit 0
          fi

          MESSAGE="$(cat <<'EOF'
          ✅ 发布验收测试通过
          仓库：${{ github.repository }}
          分支：${{ github.event.workflow_run.head_branch || github.ref_name }}
          提交：${{ github.event.workflow_run.head_sha || github.sha }}
          Staging：${{ env.STAGING_BASE_URL }}
          Artifact：${{ env.ACCEPTANCE_ARTIFACT_NAME }}
          运行记录：${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
          EOF
          )"

          curl -fsS -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \
            --data-urlencode "chat_id=${TG_CHAT_ID}" \
            --data-urlencode "text=${MESSAGE}" || echo "Telegram 通知发送失败，但验收结果不受影响。"

      - name: Telegram 失败通知
        if: failure()
        env:
          TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
          TG_CHAT_ID: ${{ secrets.TG_CHAT_ID }}
        run: |
          if [ -z "${TG_BOT_TOKEN:-}" ] || [ -z "${TG_CHAT_ID:-}" ]; then
            echo "Telegram 密钥未配置，跳过通知。"
            exit 0
          fi

          MESSAGE="$(cat <<'EOF'
          ❌ 发布验收测试失败
          仓库：${{ github.repository }}
          分支：${{ github.event.workflow_run.head_branch || github.ref_name }}
          提交：${{ github.event.workflow_run.head_sha || github.sha }}
          Staging：${{ env.STAGING_BASE_URL }}
          Artifact：${{ env.ACCEPTANCE_ARTIFACT_NAME }}
          运行记录：${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
          EOF
          )"

          curl -fsS -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \
            --data-urlencode "chat_id=${TG_CHAT_ID}" \
            --data-urlencode "text=${MESSAGE}" || echo "Telegram 通知发送失败，工作流失败状态已记录。"
