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
          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
    # pull_request 이벤트에서만 실행 — merge_group payload에는 pull_request.* 필드가 없어 오판정 위험
    if: github.event_name == 'pull_request'
    needs: []
    env:
      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: Run Gemini evidence 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" || -z "$PR" ]]; then
            echo "::error::missing pull_request payload (SHA=$SHA PR=$PR)"
            exit 1
          fi
          python3 scripts/gemini_review_gate.py \
            --pr-number "$PR" \
            --commit-sha "$SHA" \
            --check-name "gemini-review-gate" \
            --publish-check

  phase3-merge-gate:
    name: phase3-merge-gate
    runs-on: ubuntu-latest
    # pull_request 이벤트에서만 실행 — gemini-review-gate와 동일 조건
    if: github.event_name == 'pull_request'
    needs: []
    env:
      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: Run Phase 3 evidence gate (alias)
        env:
          WORKSPACE: ${{ github.workspace }}
        run: |
          set -euo pipefail
          SHA="${{ github.event.pull_request.head.sha }}"
          PR="${{ github.event.pull_request.number }}"
          if [[ -z "$SHA" || -z "$PR" ]]; then
            echo "::error::missing pull_request payload (SHA=$SHA PR=$PR)"
            exit 1
          fi
          python3 scripts/gemini_review_gate.py \
            --pr-number "$PR" \
            --commit-sha "$SHA" \
            --check-name "phase3-merge-gate" \
            --publish-check

  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)"
