name: 'Grid Review'
description: 'AI-powered code review using The Grid'
author: 'James Weatherhead'
branding:
  icon: 'grid'
  color: 'blue'

inputs:
  anthropic-api-key:
    description: 'Anthropic API key for Claude'
    required: true
  review-type:
    description: 'Type of review: full, security, quality'
    required: false
    default: 'full'
  model-tier:
    description: 'Model tier: quality, balanced, budget'
    required: false
    default: 'balanced'
  fail-on:
    description: 'Fail threshold: error, warning, none'
    required: false
    default: 'error'
  output-format:
    description: 'Output format: json, markdown, sarif'
    required: false
    default: 'markdown'
  files:
    description: 'Files to review (glob pattern)'
    required: false
    default: ''

outputs:
  status:
    description: 'Review status: pass, warn, fail'
  issues-count:
    description: 'Number of issues found'
  security-issues:
    description: 'Number of security issues'
  report-path:
    description: 'Path to the generated report'

runs:
  using: 'composite'
  steps:
    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '20'

    - name: Install Claude Code
      shell: bash
      run: |
        npm install -g @anthropic-ai/claude-code

    - name: Install The Grid
      shell: bash
      run: |
        npm install -g the-grid-cc

    - name: Get changed files
      id: changed-files
      shell: bash
      run: |
        if [ -n "${{ inputs.files }}" ]; then
          echo "files=${{ inputs.files }}" >> $GITHUB_OUTPUT
        elif [ "${{ github.event_name }}" == "pull_request" ]; then
          FILES=$(gh pr diff ${{ github.event.pull_request.number }} --name-only | tr '\n' ' ')
          echo "files=$FILES" >> $GITHUB_OUTPUT
        else
          FILES=$(git diff --name-only HEAD~1 | tr '\n' ' ')
          echo "files=$FILES" >> $GITHUB_OUTPUT
        fi
      env:
        GH_TOKEN: ${{ github.token }}

    - name: Run Grid Review
      id: review
      shell: bash
      run: |
        export ANTHROPIC_API_KEY="${{ inputs.anthropic-api-key }}"
        export GRID_MODEL_TIER="${{ inputs.model-tier }}"

        # Create output directory
        mkdir -p .grid-review

        # Build review prompt based on review type
        REVIEW_TYPE="${{ inputs.review-type }}"
        case "$REVIEW_TYPE" in
          security)
            REVIEW_PROMPT="You are a Grid Security Recognizer. Review these files for security vulnerabilities, injection risks, authentication issues, and data exposure. Focus only on security concerns."
            ;;
          quality)
            REVIEW_PROMPT="You are a Grid Quality Recognizer. Review these files for code quality, maintainability, best practices, and potential bugs. Focus on code quality and correctness."
            ;;
          *)
            REVIEW_PROMPT="You are a Grid Recognizer. Perform a comprehensive code review covering: 1) Security vulnerabilities 2) Code quality issues 3) Potential bugs 4) Test coverage gaps 5) Performance concerns"
            ;;
        esac

        # Run review with Claude Code headless mode
        claude -p "$REVIEW_PROMPT

Files to review: ${{ steps.changed-files.outputs.files }}

Return your analysis in the following JSON format:
{
  \"status\": \"pass|warn|fail\",
  \"summary\": \"Brief overall summary\",
  \"issues\": [
    {
      \"severity\": \"error|warning|info\",
      \"category\": \"security|quality|bug|performance|testing\",
      \"file\": \"path/to/file\",
      \"line\": 123,
      \"message\": \"Description of the issue\",
      \"suggestion\": \"How to fix it\"
    }
  ],
  \"stats\": {
    \"files_reviewed\": 0,
    \"errors\": 0,
    \"warnings\": 0,
    \"info\": 0
  }
}" \
          --allowedTools "Read,Grep,Glob" \
          --output-format json \
          > .grid-review/report.json 2>&1 || true

        # Convert to requested output format
        OUTPUT_FORMAT="${{ inputs.output-format }}"

        if [ "$OUTPUT_FORMAT" == "markdown" ]; then
          # Convert JSON to Markdown
          cat .grid-review/report.json | jq -r '
            "## Grid Code Review Results\n\n" +
            "**Status:** " + (.result // . | fromjson? // . | .status // "unknown") + "\n\n" +
            "### Summary\n" + (.result // . | fromjson? // . | .summary // "No summary available") + "\n\n" +
            "### Issues Found\n\n" +
            ((.result // . | fromjson? // . | .issues // []) | map(
              "- **[" + .severity + "]** `" + .file + ":" + (.line | tostring) + "` - " + .message + "\n  > " + .suggestion
            ) | join("\n\n")) +
            "\n\n---\n*Powered by The Grid*"
          ' > .grid-review/report.markdown 2>/dev/null || cp .grid-review/report.json .grid-review/report.markdown
        elif [ "$OUTPUT_FORMAT" == "sarif" ]; then
          # Convert JSON to SARIF format for GitHub Code Scanning
          cat .grid-review/report.json | jq '
            {
              "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
              "version": "2.1.0",
              "runs": [{
                "tool": {
                  "driver": {
                    "name": "Grid Review",
                    "version": "1.7.x",
                    "informationUri": "https://github.com/JamesWeatherhead/grid",
                    "rules": []
                  }
                },
                "results": ((.result // . | fromjson? // . | .issues // []) | map({
                  "ruleId": .category,
                  "level": (if .severity == "error" then "error" elif .severity == "warning" then "warning" else "note" end),
                  "message": { "text": .message },
                  "locations": [{
                    "physicalLocation": {
                      "artifactLocation": { "uri": .file },
                      "region": { "startLine": .line }
                    }
                  }]
                }))
              }]
            }
          ' > .grid-review/report.sarif 2>/dev/null || echo '{"version":"2.1.0","runs":[]}' > .grid-review/report.sarif
        fi

        # Parse results for outputs
        if [ -f ".grid-review/report.json" ]; then
          # Try to parse the JSON result
          PARSED=$(cat .grid-review/report.json | jq -r '.result // .' 2>/dev/null || cat .grid-review/report.json)
          STATUS=$(echo "$PARSED" | jq -r 'if type == "string" then fromjson else . end | .status // "unknown"' 2>/dev/null || echo "unknown")
          ISSUES=$(echo "$PARSED" | jq -r 'if type == "string" then fromjson else . end | .issues | length // 0' 2>/dev/null || echo "0")
          SECURITY=$(echo "$PARSED" | jq -r 'if type == "string" then fromjson else . end | [.issues[] | select(.category == "security")] | length // 0' 2>/dev/null || echo "0")
        else
          STATUS="unknown"
          ISSUES="0"
          SECURITY="0"
        fi

        echo "status=$STATUS" >> $GITHUB_OUTPUT
        echo "issues-count=$ISSUES" >> $GITHUB_OUTPUT
        echo "security-issues=$SECURITY" >> $GITHUB_OUTPUT
        echo "report-path=.grid-review/report.${{ inputs.output-format }}" >> $GITHUB_OUTPUT

    - name: Upload SARIF (if applicable)
      if: inputs.output-format == 'sarif'
      uses: github/codeql-action/upload-sarif@v3
      with:
        sarif_file: .grid-review/report.sarif

    - name: Comment on PR
      if: github.event_name == 'pull_request' && inputs.output-format == 'markdown'
      shell: bash
      run: |
        if [ -f ".grid-review/report.markdown" ]; then
          gh pr comment ${{ github.event.pull_request.number }} \
            --body-file .grid-review/report.markdown
        fi
      env:
        GH_TOKEN: ${{ github.token }}

    - name: Check fail threshold
      shell: bash
      run: |
        STATUS="${{ steps.review.outputs.status }}"
        FAIL_ON="${{ inputs.fail-on }}"

        if [ "$FAIL_ON" == "none" ]; then
          echo "Fail threshold set to 'none' - always passing"
          exit 0
        elif [ "$FAIL_ON" == "warning" ] && [ "$STATUS" != "pass" ]; then
          echo "::error::Review found warnings or errors (status: $STATUS)"
          exit 1
        elif [ "$FAIL_ON" == "error" ] && [ "$STATUS" == "fail" ]; then
          echo "::error::Review found errors (status: $STATUS)"
          exit 1
        fi

        echo "Review completed with status: $STATUS"
