name: IPZ Gate Backstop

on: [push, pull_request]

jobs:
  protected-paths:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: ${{ github.event.pull_request.head.sha || github.sha }}
      - name: Compute changed files
        shell: bash
        run: |
          set -euo pipefail
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            range="origin/${{ github.base_ref }}...HEAD"
          else
            before="${{ github.event.before }}"
            if [ "$before" = "0000000000000000000000000000000000000000" ]; then
              if git rev-parse --verify HEAD~1 >/dev/null 2>&1; then
                range="HEAD~1...HEAD"
              else
                range="$(git hash-object -t tree /dev/null)..HEAD"
              fi
            else
              range="$before...${{ github.sha }}"
            fi
          fi
          git diff --name-only -z "$range" > changed-files.z
      - name: Require approval for protected paths
        shell: bash
        run: |
          set -euo pipefail
          protected_path_changed=false
          while IFS= read -r -d '' file; do
            case "$file" in
              .dev-config/hooks/*|.dev-config/bin/ipz-remote-php-gate|.dev-config/bin/install-ipz-gate|.dev-config/bin/approve-gate-change|.github/*)
                protected_path_changed=true
                break
                ;;
            esac
          done < changed-files.z
          if [ "$protected_path_changed" = false ]; then
            echo "No protected paths changed."
            exit 0
          fi
          if ! git log -1 --format=%B HEAD | grep -qx 'Gate-Change-Approved: yes'; then
            echo "Protected gate paths changed. Add the exact commit-message trailer: Gate-Change-Approved: yes"
            exit 1
          fi

  eslint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: ${{ github.event.pull_request.head.sha || github.sha }}
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - name: Install lint dependencies
        run: npm ci --prefix .dev-config
      - name: Lint changed JavaScript and TypeScript files
        shell: bash
        run: |
          set -euo pipefail
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            range="origin/${{ github.base_ref }}...HEAD"
          else
            before="${{ github.event.before }}"
            if [ "$before" = "0000000000000000000000000000000000000000" ]; then
              if git rev-parse --verify HEAD~1 >/dev/null 2>&1; then
                range="HEAD~1...HEAD"
              else
                range="$(git hash-object -t tree /dev/null)..HEAD"
              fi
            else
              range="$before...${{ github.sha }}"
            fi
          fi
          changed_files=$(mktemp)
          trap 'rm -f "$changed_files"' EXIT
          git diff --name-only -z --diff-filter=ACMRT "$range" -- '*.js' '*.jsx' '*.ts' '*.tsx' > "$changed_files"
          mapfile -d '' -t files < "$changed_files"
          if [ "${#files[@]}" -eq 0 ]; then
            echo "No JavaScript or TypeScript files changed."
            exit 0
          fi
          if [ -x .dev-config/bin/lint ]; then
            .dev-config/bin/lint --max-warnings 9999 -- "${files[@]}"
          else
            npx --prefix .dev-config eslint -c .dev-config/eslint.config.mjs -- "${files[@]}"
          fi

  php-audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: ${{ github.event.pull_request.head.sha || github.sha }}
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
          tools: composer
      - name: Audit changed PHP files and dependencies
        shell: bash
        run: |
          set -euo pipefail
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            range="origin/${{ github.base_ref }}...HEAD"
          else
            before="${{ github.event.before }}"
            if [ "$before" = "0000000000000000000000000000000000000000" ]; then
              if git rev-parse --verify HEAD~1 >/dev/null 2>&1; then
                range="HEAD~1...HEAD"
              else
                range="$(git hash-object -t tree /dev/null)..HEAD"
              fi
            else
              range="$before...${{ github.sha }}"
            fi
          fi
          changed_files=$(mktemp)
          trap 'rm -f "$changed_files"' EXIT
          git diff --name-only -z --diff-filter=ACMRT "$range" -- '*.php' > "$changed_files"
          php_files=0
          while IFS= read -r -d '' file; do
            if [[ "$file" == *.php ]]; then
              php -l -- "$file"
              php_files=$((php_files + 1))
            fi
          done < "$changed_files"
          if [ "$php_files" -eq 0 ]; then
            echo "No PHP files changed."
          fi
          if [ -f plugins/international-press-zone/composer.lock ]; then
            composer audit --locked --working-dir=plugins/international-press-zone
          else
            echo "No International Press Zone composer.lock to audit."
          fi
