name: ProxyHawk Guard check

# Public copy: https://proxyhawk.io/guard-ci/workflows/check.yml
# Docs: https://proxyhawk.io/docs/guard-ci-onboarding.html

on:
  workflow_call:
    inputs:
      environment:
        description: "Guard environment label (must match session routing + GitHub mapping)"
        required: true
        type: string
      api_url:
        description: "Public API base URL for the deployed environment"
        required: true
        type: string
      commit_sha:
        description: "Commit SHA expected to be live (defaults to github.sha)"
        required: false
        type: string
      wait_for_deploy:
        description: "Poll health endpoint until gitSha matches commit_sha before running Guard"
        required: false
        type: boolean
        default: false
      health_path:
        description: "Health check path for wait-for-deploy"
        required: false
        type: string
        default: "/api/health"
      service_name:
        description: "Optional monorepo service key for mapping lookup"
        required: false
        type: string
        default: ""
      fail_on_guard_issues:
        description: "Fail the job when Guard detects violations. Default false (warning mode) — switch to true once you trust Guard output on your API."
        required: false
        type: boolean
        default: false
      github_comment:
        description: "Upsert a PR comment with Guard results (requires GITHUB_TOKEN)"
        required: false
        type: boolean
        default: false
      guard_base_url:
        description: "Optional deploy host override for endpoint replay"
        required: false
        type: string
        default: ""
      runner_platform:
        description: "Runner platform (linux-amd64 | linux-arm64)"
        required: false
        type: string
        default: "linux-amd64"
    secrets:
      PROXYHAWK_API_EMAIL:
        required: true
      PROXYHAWK_API_PASSWORD:
        required: true
      PROXYHAWK_API_BASE_URL:
        required: false
      PROXYHAWK_API_TOKEN:
        required: false
      PROXYHAWK_GUARD_WORKSPACE_ID:
        required: false
      PROXYHAWK_GUARD_RUNNER_URL:
        required: false
      PROXYHAWK_GUARD_RUNNER_TOKEN:
        required: false
    outputs:
      guard_exit_code:
        description: "Exit code from proxyhawk-guard check (0 = pass)"
        value: ${{ jobs.guard-check.outputs.guard_exit_code }}

permissions:
  contents: read
  # pull-requests: write — only if caller sets github_comment: true on this workflow

jobs:
  guard-check:
    name: ProxyHawk Guard check
    runs-on: ubuntu-latest
    outputs:
      guard_exit_code: ${{ steps.guard.outputs.exit_code }}
    env:
      PROXYHAWK_API_BASE_URL: ${{ vars.PROXYHAWK_API_BASE_URL || secrets.PROXYHAWK_API_BASE_URL || 'https://api.proxyhawk.io' }}
      PROXYHAWK_GUARD_TROUBLESHOOTING_URL: https://proxyhawk.io/docs/guard-ci-existing-pipeline.html#troubleshooting
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Login to ProxyHawk API
        env:
          PROXYHAWK_API_EMAIL: ${{ secrets.PROXYHAWK_API_EMAIL }}
          PROXYHAWK_API_PASSWORD: ${{ secrets.PROXYHAWK_API_PASSWORD }}
          PROXYHAWK_API_TOKEN: ${{ secrets.PROXYHAWK_API_TOKEN }}
        run: |
          if [ -n "${PROXYHAWK_API_TOKEN:-}" ]; then
            echo "Using PROXYHAWK_API_TOKEN from secrets."
            echo "PROXYHAWK_API_TOKEN=${PROXYHAWK_API_TOKEN}" >> "$GITHUB_ENV"
            exit 0
          fi
          body=$(curl -sS \
            -H "Content-Type: application/json" \
            -H "ngrok-skip-browser-warning: true" \
            -d "{\"email\":\"${PROXYHAWK_API_EMAIL}\",\"password\":\"${PROXYHAWK_API_PASSWORD}\"}" \
            "${PROXYHAWK_API_BASE_URL%/}/api/v1/auth/login")
          token=$(echo "$body" | python3 -c "import sys,json; print(json.load(sys.stdin).get('accessToken',''))" 2>/dev/null || true)
          if [ -z "$token" ]; then
            echo "ProxyHawk login failed: $body"
            echo "Troubleshooting: ${PROXYHAWK_GUARD_TROUBLESHOOTING_URL}"
            exit 1
          fi
          echo "::add-mask::$token"
          echo "PROXYHAWK_API_TOKEN=$token" >> "$GITHUB_ENV"

      - name: Resolve guard-runner binary
        id: runner
        env:
          RUNNER_URL: ${{ secrets.PROXYHAWK_GUARD_RUNNER_URL }}
          RUNNER_TOKEN: ${{ secrets.PROXYHAWK_GUARD_RUNNER_TOKEN }}
          RUNNER_PLATFORM: ${{ inputs.runner_platform }}
        run: |
          if [ -x "$GITHUB_WORKSPACE/tools/guard-runner/target/release/proxyhawk-guard" ]; then
            echo "Using vendored guard-runner binary (release build)."
            echo "runner_path=$GITHUB_WORKSPACE/tools/guard-runner/target/release/proxyhawk-guard" >> "$GITHUB_OUTPUT"
            exit 0
          fi
          if [ -x "$GITHUB_WORKSPACE/tools/guard-runner/proxyhawk-guard" ]; then
            echo "Using vendored guard-runner binary."
            echo "runner_path=$GITHUB_WORKSPACE/tools/guard-runner/proxyhawk-guard" >> "$GITHUB_OUTPUT"
            exit 0
          fi

          token="${PROXYHAWK_API_TOKEN:-}"
          if [ -z "$token" ]; then
            echo "PROXYHAWK_API_TOKEN is required to download the runner binary."
            exit 1
          fi

          if [ -z "$RUNNER_URL" ]; then
            echo "Requesting short-lived signed runner URL from ProxyHawk backend."
            runner_resp="$(mktemp)"
            http_code=$(curl -sS -o "$runner_resp" -w "%{http_code}" \
              -H "Authorization: Bearer ${token}" \
              -H "ngrok-skip-browser-warning: true" \
              "${PROXYHAWK_API_BASE_URL%/}/api/v1/guard/runner/download-url?platform=${RUNNER_PLATFORM}")
            RUNNER_URL=$(python3 -c "import json,sys; print(json.load(open(sys.argv[1])).get('downloadUrl',''))" "$runner_resp" 2>/dev/null || true)
            if [ -z "$RUNNER_URL" ]; then
              echo "Failed to obtain signed runner URL (HTTP ${http_code})."
              cat "$runner_resp" || true
              echo ""
              echo "Common causes:"
              echo "  • Backend missing PROXYHAWK_GUARD_RUNNER_SIGNING_SECRET or runner binary path"
              echo "  • Account/plan missing guard_api_regression entitlement"
              echo "Fallback: set PROXYHAWK_GUARD_RUNNER_URL secret to a direct .tar.gz or binary URL."
              echo "Troubleshooting: ${PROXYHAWK_GUARD_TROUBLESHOOTING_URL}"
              rm -f "$runner_resp"
              exit 1
            fi
            rm -f "$runner_resp"
          fi

          tmp_payload="$(mktemp)"
          mkdir -p "$GITHUB_WORKSPACE/.proxyhawk/bin"
          auth_args=()
          if [ -n "$RUNNER_TOKEN" ]; then
            auth_args=(-H "Authorization: Bearer ${RUNNER_TOKEN}")
          fi
          curl -fsSL "${auth_args[@]}" "$RUNNER_URL" -o "$tmp_payload"

          runner_path="$GITHUB_WORKSPACE/.proxyhawk/bin/proxyhawk-guard"
          if tar -tzf "$tmp_payload" >/dev/null 2>&1; then
            tmp_extract="$(mktemp -d)"
            tar -xzf "$tmp_payload" -C "$tmp_extract"
            if [ -f "$tmp_extract/proxyhawk-guard" ]; then
              install -m 0755 "$tmp_extract/proxyhawk-guard" "$runner_path"
            elif [ -f "$tmp_extract/bin/proxyhawk-guard" ]; then
              install -m 0755 "$tmp_extract/bin/proxyhawk-guard" "$runner_path"
            else
              found="$(find "$tmp_extract" -type f -name proxyhawk-guard | head -1 || true)"
              if [ -z "$found" ]; then
                echo "Downloaded tarball does not contain proxyhawk-guard binary."
                exit 1
              fi
              install -m 0755 "$found" "$runner_path"
            fi
          else
            install -m 0755 "$tmp_payload" "$runner_path"
          fi

          if [ ! -x "$runner_path" ]; then
            echo "guard-runner binary is not executable after download."
            exit 1
          fi
          echo "runner_path=$runner_path" >> "$GITHUB_OUTPUT"

      - name: Run Guard check
        id: guard
        env:
          PROXYHAWK_API_EMAIL: ${{ secrets.PROXYHAWK_API_EMAIL }}
          PROXYHAWK_API_PASSWORD: ${{ secrets.PROXYHAWK_API_PASSWORD }}
          PROXYHAWK_API_TOKEN: ${{ secrets.PROXYHAWK_API_TOKEN }}
          PROXYHAWK_GUARD_WORKSPACE_ID: ${{ secrets.PROXYHAWK_GUARD_WORKSPACE_ID }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GUARD_BASE_URL: ${{ inputs.guard_base_url }}
          PROXYHAWK_GUARD_SERVICE: ${{ inputs.service_name }}
        run: |
          set +e
          extra_args=()
          if [ "${{ inputs.wait_for_deploy }}" = "true" ]; then
            extra_args+=(--wait-for-deploy)
          fi
          if [ -n "${{ inputs.health_path }}" ]; then
            extra_args+=(--health-path "${{ inputs.health_path }}")
          fi
          if [ -n "${{ inputs.guard_base_url }}" ]; then
            extra_args+=(--base-url "${{ inputs.guard_base_url }}")
          fi
          if [ -n "${{ inputs.service_name }}" ]; then
            extra_args+=(--service "${{ inputs.service_name }}")
          fi
          if [ "${{ inputs.github_comment }}" = "true" ]; then
            extra_args+=(--github-comment)
          fi

          commit_sha="${{ inputs.commit_sha }}"
          if [ -z "$commit_sha" ]; then
            commit_sha="${{ github.sha }}"
          fi

          "${{ steps.runner.outputs.runner_path }}" check \
            --environment "${{ inputs.environment }}" \
            --api-url "${{ inputs.api_url }}" \
            --commit-sha "$commit_sha" \
            "${extra_args[@]}"
          exit_code=$?
          set -e
          echo "exit_code=$exit_code" >> "$GITHUB_OUTPUT"
          if [ "${{ inputs.fail_on_guard_issues }}" = "true" ] && [ "$exit_code" -ne 0 ]; then
            echo "ProxyHawk Guard check failed (exit $exit_code)."
            echo "Troubleshooting: ${PROXYHAWK_GUARD_TROUBLESHOOTING_URL}"
            exit "$exit_code"
          fi
          if [ "$exit_code" -ne 0 ]; then
            echo "ProxyHawk Guard reported issues (fail_on_guard_issues=false; job continues)."
          fi
