name: CI
on:
  pull_request:
    branches: [main]
  merge_group:

permissions:
  contents: read
  checks: write
  pull-requests: write
  issues: write
  statuses: write

jobs:
  cancel-kill-switch:
    name: cancel-kill-switch
    runs-on: ubuntu-latest
    if: always()
    needs: []
    steps:
      - uses: actions/checkout@v4
      - name: Cancel kill-switch (cancelled marker)
        run: |
          set -euo pipefail
          REF="${{ github.head_ref }}${{ github.ref }}"
          TASK_ID=$(echo "$REF" | grep -oE 'task-[0-9]+' | head -n1 || true)
          if [[ -n "$TASK_ID" && -f "memory/events/${TASK_ID}.cancelled" ]]; then
            echo "::error::Cancelled task — CI FAIL ($TASK_ID)"
            exit 1
          fi
          echo "OK: no cancellation marker (task=$TASK_ID)"

  qc-check:
    name: qc-check
    runs-on: ubuntu-latest
    if: always()
    needs: []
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Run guard.sh qc-check
        env:
          WORKSPACE: ${{ github.workspace }}
        run: |
          set -euo pipefail
          TASK_ID=$(echo "${{ github.head_ref }}" | grep -oE 'task-[0-9]+' | head -n1 || true)
          if [[ -z "$TASK_ID" ]]; then
            echo "no task id detected — skipping qc-check"
          elif [[ ! -f "memory/events/${TASK_ID}.qc-result" ]]; then
            echo "qc-result 미생성 (PR 단계 정상) — graceful pass: ${TASK_ID}"
          else
            bash scripts/guard.sh qc-check "$TASK_ID"
          fi

  hidden-path-audit:
    name: hidden-path-audit
    runs-on: ubuntu-latest
    if: always()
    needs: []
    steps:
      - uses: actions/checkout@v4
      - name: Detect unguarded merge calls
        run: |
          set -euo pipefail
          # task-2463 P0-2: worktree_manager.py에서 gh pr merge 발견 시 fail
          WT_MGR_VIOLATIONS=$(grep -nE 'subprocess\.[a-z_]+\(\[?"gh", "pr", "merge"|\["gh", "pr", "merge"' scripts/worktree_manager.py 2>/dev/null || true)
          if [[ -n "$WT_MGR_VIOLATIONS" ]]; then
            echo "::error::P0-2 위반: worktree_manager.py에 gh pr merge 직접 호출 발견"
            echo "$WT_MGR_VIOLATIONS"
            exit 1
          fi
          echo "[hidden-path-audit] worktree_manager.py gh pr merge 0건 PASS (task-2463 P0-2)"
          UNGUARDED=$(grep -rn -E "gh pr merge|git push.*origin main|worktree_manager.*finish" \
            --include='*.py' --include='*.sh' scripts/ \
            | grep -v "guard\|cancelled\|docstring\|comment\|# " \
            || true)
          COUNT=$(printf '%s\n' "$UNGUARDED" | grep -c . || true)
          echo "candidate matches: $COUNT"
          printf '%s\n' "$UNGUARDED"

  lock-in-check:
    name: lock-in-check
    runs-on: ubuntu-latest
    if: always()
    needs: []
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: AST verify First-line guard
        env:
          WORKSPACE: ${{ github.workspace }}
        run: |
          set -euo pipefail
          python3 scripts/lock_in_verify.py

  merge-safety-check:
    name: merge-safety-check
    runs-on: ubuntu-latest
    if: always()
    needs: []
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Run guard.sh pre-push
        env:
          WORKSPACE: ${{ github.workspace }}
        run: |
          set -euo pipefail
          TASK_ID=$(echo "${{ github.head_ref }}" | grep -oE 'task-[0-9]+' | head -n1 || true)
          if [[ -z "$TASK_ID" ]]; then
            echo "no task id detected — skipping merge-safety-check"
          elif [[ ! -f "memory/tasks/${TASK_ID}.md" ]]; then
            echo "task 파일 미존재 (PR 단계 정상) — graceful pass: ${TASK_ID}"
          else
            bash scripts/guard.sh pre-push "$TASK_ID"
          fi

  gemini-review-gate:
    name: gemini-review-gate
    runs-on: ubuntu-latest
    if: always()
    needs: []
    env:
      GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Mark check pending
        if: ${{ github.event.pull_request.head.sha != '' }}
        run: |
          set -euo pipefail
          python3 scripts/gemini_review_gate.py \
            --pr-number "${{ github.event.pull_request.number }}" \
            --commit-sha "${{ github.event.pull_request.head.sha }}" \
            --status pending || true
      - name: Run Gemini review gate
        env:
          WORKSPACE: ${{ github.workspace }}
        run: |
          set -euo pipefail
          SHA="${{ github.event.pull_request.head.sha }}"
          PR="${{ github.event.pull_request.number }}"
          if [[ -z "$SHA" ]]; then SHA="${{ github.sha }}"; fi
          python3 scripts/gemini_review_gate.py \
            --pr-number "${PR:-0}" \
            --commit-sha "$SHA" \
            --publish-check

  phase3-merge-gate:
    name: phase3-merge-gate
    runs-on: ubuntu-latest
    if: always()
    needs: []
    env:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - uses: actions/checkout@v4
      - name: Verify Gemini review presence on PR
        if: ${{ github.event.pull_request.number != '' }}
        run: |
          set -euo pipefail
          PR="${{ github.event.pull_request.number }}"
          if [[ -z "$PR" ]]; then
            echo "[phase3-merge-gate] PR number not detected — skipping (push event)"
            exit 0
          fi
          REVIEWS=$(gh api "repos/${{ github.repository }}/pulls/$PR/reviews" 2>/dev/null || echo "[]")
          GEMINI_COUNT=$(echo "$REVIEWS" | python3 -c "
          import json, sys
          try:
              data = json.loads(sys.stdin.read())
              count = sum(1 for r in data if 'gemini-code-assist' in (r.get('user', {}).get('login', '') or '').lower())
              print(count)
          except Exception:
              print(0)
          ")
          echo "[phase3-merge-gate] Gemini review count: $GEMINI_COUNT"
          if [ "$GEMINI_COUNT" = "0" ]; then
            echo "::error::phase3-merge-gate: gemini-code-assist review 0건 — merge 차단 (task-2463 P0-3)"
            exit 1
          fi
          echo "[phase3-merge-gate] PASS"

  ci-guard:
    name: ci/guard
    runs-on: ubuntu-latest
    if: always()
    needs: []
    steps:
      - run: echo "all required checks passed"

  guard:
    name: guard
    runs-on: ubuntu-latest
    if: always()
    needs: []
    steps:
      - uses: actions/checkout@v4
      - name: Guard wrap-up check
        env:
          WORKSPACE: ${{ github.workspace }}
        run: |
          set -euo pipefail
          REF="${{ github.head_ref }}${{ github.ref }}"
          TASK_ID=$(echo "$REF" | grep -oE 'task-[0-9]+' | head -n1 || true)
          if [[ -z "$TASK_ID" ]]; then
            echo "::error::guard: task-id 추출 실패 (branch=$REF)"
            exit 1
          fi
          if [[ -f "memory/events/${TASK_ID}.cancelled" ]]; then
            echo "::error::guard: task $TASK_ID cancelled"
            exit 1
          fi
          for f in scripts/guard.sh scripts/pre_push_guard.py scripts/qc_report_guard.py; do
            if [[ ! -f "$f" ]]; then
              echo "::error::guard: required guard file missing: $f"
              exit 1
            fi
          done
          echo "OK: guard wrap-up PASS (task=$TASK_ID)"
