name: Vulnerability Scan

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]
  schedule:
    # Run weekly on Monday at 2 AM UTC
    - cron: '0 2 * * 1'
  workflow_dispatch:

jobs:
  scan-go-dependencies:
    name: Scan Go Dependencies (govulncheck)
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version: '1.23'
          check-latest: true

      - name: Install govulncheck
        run: |
          go install golang.org/x/vuln/cmd/govulncheck@latest

      - name: Run govulncheck
        id: vulncheck
        continue-on-error: true
        run: |
          echo "Scanning Go dependencies for vulnerabilities..."
          govulncheck ./... > vulncheck-report.txt 2>&1 || true
          echo "report<<EOF" >> $GITHUB_OUTPUT
          cat vulncheck-report.txt >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Upload govulncheck report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: govulncheck-report
          path: vulncheck-report.txt
          retention-days: 30

      - name: Check for HIGH/CRITICAL vulnerabilities
        id: check-severity
        run: |
          if grep -iE "(HIGH|CRITICAL)" vulncheck-report.txt > /dev/null 2>&1; then
            echo "found_critical=true" >> $GITHUB_OUTPUT
            echo "❌ HIGH or CRITICAL vulnerabilities found!"
            cat vulncheck-report.txt
            exit 1
          else
            echo "found_critical=false" >> $GITHUB_OUTPUT
            echo "✅ No HIGH or CRITICAL vulnerabilities found"
            if [ -s vulncheck-report.txt ]; then
              echo "⚠️  Some vulnerabilities found (not HIGH/CRITICAL):"
              cat vulncheck-report.txt
            fi
          fi

      - name: Comment PR with results
        if: github.event_name == 'pull_request' && always()
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            let report = 'No vulnerabilities found';
            if (fs.existsSync('vulncheck-report.txt')) {
              report = fs.readFileSync('vulncheck-report.txt', 'utf8');
            }
            const body = `## 🔒 Go Dependency Vulnerability Scan Results
            
            \`\`\`
            ${report}
            \`\`\`
            
            ${steps.check-severity.outputs.found_critical === 'true' ? '❌ **HIGH or CRITICAL vulnerabilities detected**' : '✅ **No HIGH or CRITICAL vulnerabilities**'}
            `;
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: body
            });

  scan-docker-image:
    name: Scan Docker Image (Trivy)
    runs-on: ubuntu-latest
    if: github.event_name != 'schedule' || github.event_name == 'workflow_dispatch'
    permissions:
      contents: read
      security-events: write
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: false
          tags: veza-backend-api:scan
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'veza-backend-api:scan'
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'
          ignore-unfixed: false

      - name: Upload Trivy results to GitHub Security
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: 'trivy-results.sarif'

      - name: Upload Trivy report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: trivy-report
          path: trivy-results.sarif
          retention-days: 30

      - name: Run Trivy with table output
        continue-on-error: true
        run: |
          docker run --rm \
            -v /var/run/docker.sock:/var/run/docker.sock \
            aquasec/trivy:latest image veza-backend-api:scan \
            --format table \
            --severity CRITICAL,HIGH

  scan-docker-image-report-only:
    name: Scan Docker Image (Report Only)
    runs-on: ubuntu-latest
    if: github.event_name == 'schedule'
    permissions:
      contents: read
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: false
          tags: veza-backend-api:scan
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Run Trivy vulnerability scanner (Report Only)
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'veza-backend-api:scan'
          format: 'table'
          exit-code: '0'
          severity: 'CRITICAL,HIGH,MEDIUM,LOW'
          ignore-unfixed: false

      - name: Upload Trivy report
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: trivy-report-scheduled
          path: trivy-results.txt
          retention-days: 30
