name: 코드 리뷰
on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
permissions:
  pull-requests: write
  contents: read
  issues: write
jobs:
  code-review:
    runs-on: ubuntu-latest
    # 드래프트 PR은 자동 코드 리뷰 건너뛰기
    if: github.event.pull_request.draft == false
    steps:
      - name: 리포지토리 체크아웃
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: ${{ github.event.pull_request.head.sha }}
      - name: Cursor CLI 설치
        run: |
          curl https://cursor.com/install -fsS | bash
          echo "$HOME/.cursor/bin" >> $GITHUB_PATH
      - name: git 사용자 정보 설정
        run: |
          git config user.name "Cursor 에이전트"
          git config user.email "cursoragent@cursor.com"
      - name: 자동 코드 리뷰 실행
        env:
          CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }}
          MODEL: gpt-5
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          BLOCKING_REVIEW: ${{ vars.BLOCKING_REVIEW || 'false' }}
        run: |
          cursor-agent --force --model "$MODEL" --output-format=text --print 'GitHub Actions 러너에서 자동 코드 리뷰를 수행 중이야. gh CLI는 GH_TOKEN으로 인증되어 있고 사용 가능해. 풀 리퀘스트에 코멘트를 남길 수 있어.
          컨텍스트:
          - 리포지토리: ${{ github.repository }}
          - PR 번호: ${{ github.event.pull_request.number }}
          - PR 헤드 SHA: ${{ github.event.pull_request.head.sha }}
          - PR 베이스 SHA: ${{ github.event.pull_request.base.sha }}
          - 차단 리뷰: ${{ env.BLOCKING_REVIEW }}
          목표:
          1) 기존 리뷰 코멘트를 다시 확인하고 해결됐으면 resolved로 답장해.
          2) 현재 PR diff를 리뷰하고 명확하고 심각도가 높은 이슈만 표시해.
          3) 변경된 라인에만 아주 짧은 인라인 코멘트(1~2문장)와 끝에 간단한 요약을 남겨.
          절차:
          - 기존 코멘트 가져오기: gh pr view --json comments
          - diff 가져오기: gh pr diff
          - 인라인 위치 계산을 위한 패치 포함 변경 파일 가져오기: gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files --paginate --jq '.[] | {filename,patch}'
          - 각 이슈에 대한 정확한 인라인 앵커 계산(파일 경로 + diff 위치). 코멘트는 반드시 diff의 변경된 라인에 인라인으로 달고, 최상위 코멘트로 달면 안 돼.
          - 이 봇이 작성한 이전의 최상위 "문제 없음" 스타일 코멘트를 감지해(본문이 "✅ no issues", "No issues found", "LGTM"과 유사한 경우 매칭).
          - 이번 실행에서 이슈가 발견되고 과거 "문제 없음" 코멘트가 있으면:
            - 혼란을 피하기 위해 제거하는 걸 우선해:
              - 최상위 해당 코멘트 삭제 시도: gh api -X DELETE repos/${{ github.repository }}/issues/comments/<comment_id>
              - 삭제가 불가하면 GraphQL(minimizeComment)로 최소화하거나 "[Superseded by new findings]" 접두사를 붙여 편집해.
            - 삭제/최소화 모두 불가하면 이렇게 답장해: "⚠️ 대체됨: 최신 커밋에서 이슈가 발견됐어"
          - 이전에 보고된 이슈가 인접한 변경으로 해결된 것 같으면, 이렇게 답장해: ✅ 최근 변경으로 이 이슈가 해결된 것으로 보여
          - 다음만 분석:
            - null/undefined 역참조
            - 리소스 누수(닫히지 않은 파일 또는 연결)
            - 인젝션(SQL/XSS)
            - 동시성/경쟁 상태
            - 중요 작업의 오류 처리 누락
            - 잘못된 동작을 유발하는 명백한 로직 오류
            - 측정 가능한 영향이 있는 명확한 성능 안티패턴
            - 명백한 보안 취약점
          - 중복 방지: 동일하거나 인접한 라인에 유사한 피드백이 이미 있으면 건너뛰어.
          코멘트 규칙:
          - 인라인 코멘트 최대 10개; 가장 중요한 이슈에 우선순위를 둬
          - 코멘트당 하나의 이슈; 정확히 변경된 라인에 배치해
          - 모든 이슈 코멘트는 반드시 인라인(PR diff의 파일과 위치에 고정)
          - 자연스러운 톤으로 구체적이고 실행 가능하게; 자동화나 확신도 언급 금지
          - 이모지 사용: 🚨 중대 🔒 보안 ⚡ 성능 ⚠️ 로직 ✅ 해결 ✨ 개선
          제출:
          - 보고할 이슈가 없고 기존의 "문제 없음" 최상위 코멘트가 이미 있으면(예: "✅ no issues", "No issues found", "LGTM") 새 코멘트를 제출하지 마. 중복을 피하기 위해 건너뛰어.
          - 보고할 이슈가 없고 이전 "문제 없음" 코멘트도 없으면, 간단한 요약 코멘트 하나로 문제 없음을 알려.
          - 보고할 이슈가 있고 이전 "문제 없음" 코멘트가 있으면, 새 리뷰 제출 전에 그 코멘트를 삭제/최소화/대체됨으로 표시해.
          - 보고할 이슈가 있으면, 인라인 코멘트만 포함한 리뷰 하나와 선택적 간결 요약 본문을 제출해. 인라인을 보장하려면 GitHub Reviews API를 사용해:
            - 다음 형식의 코멘트 JSON 배열을 구성: [{ "path": "<file>", "position": <diff_position>, "body": "..." }]
            - 다음으로 제출: gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/reviews -f event=COMMENT -f body="$SUMMARY" -f comments='[$COMMENTS_JSON]'
          - 사용 금지: gh pr review --approve 또는 --request-changes
          차단 동작:
          - BLOCKING_REVIEW가 true이고 🚨 또는 🔒 이슈가 하나라도 올라왔으면: echo "CRITICAL_ISSUES_FOUND=true" >> $GITHUB_ENV
          - 그 외에는: echo "CRITICAL_ISSUES_FOUND=false" >> $GITHUB_ENV
          - 마지막에 항상 CRITICAL_ISSUES_FOUND를 설정해
          '
      - name: 차단 리뷰 결과 확인
        if: env.BLOCKING_REVIEW == 'true'
        run: |
          echo "중대한 이슈가 있는지 확인 중..."
          echo "CRITICAL_ISSUES_FOUND: ${CRITICAL_ISSUES_FOUND:-unset}"
          if [ "${CRITICAL_ISSUES_FOUND:-false}" = "true" ]; then
            echo "❌ 중대한 이슈가 발견됐고 차단 리뷰가 활성화되어 있어. 워크플로를 실패 처리할게."
            exit 1
          else
            echo "✅ 차단되는 이슈는 발견되지 않았어."
          fi