name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  CARGO_TERM_COLOR: always
  NODE_VERSION: "22.12.0"

jobs:
  fmt:
    name: Format
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt
      - run: cargo fmt --check

  clippy:
    name: Clippy
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy
      - uses: actions/cache@v5
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-clippy-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: ${{ runner.os }}-cargo-clippy-
      - run: cargo clippy -- -D warnings

  test:
    name: Test
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable
      - uses: actions/cache@v5
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-test-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: ${{ runner.os }}-cargo-test-
      - run: cargo test

  semgrep-parity:
    name: Semgrep Parity
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable
      - uses: actions/setup-python@v6
        with:
          python-version: "3.12"
      - uses: actions/cache@v5
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ubuntu-cargo-semgrep-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: ubuntu-cargo-semgrep-
      - name: Install semgrep
        run: pip install semgrep
      - name: Run Semgrep parity suite
        run: cargo test --test semgrep_parity

  website:
    name: Website Build
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: www
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: npm
          cache-dependency-path: www/package-lock.json
      - run: npm ci
      - run: npm run build

  vscode-extension:
    name: VS Code Extension
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: vscode-extension
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: npm
          cache-dependency-path: vscode-extension/package-lock.json
      - run: npm ci
      - run: npm run compile

  npm-package:
    name: npm Package
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: packages/npm
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: ${{ env.NODE_VERSION }}
      - run: npm pack --dry-run

  scripts:
    name: Script Syntax
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - run: bash -n action/entrypoint.sh
      - run: bash -n benchmarks/run.sh
      - run: bash -n scripts/release.sh

  build:
    name: Build Release
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable
      - uses: actions/cache@v5
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: ${{ runner.os }}-cargo-build-
      - run: cargo build --release

  dogfood:
    name: Dogfood (foxguard scans itself)
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable
      - uses: actions/cache@v5
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: ${{ runner.os }}-cargo-build-

      - name: Build foxguard
        run: cargo build --release

      - name: Scan own source (must be clean)
        run: ./target/release/foxguard --severity high src/

      - name: Scan own source for secrets (must be clean)
        run: ./target/release/foxguard secrets src/

      - name: Verify fixture detection (must find issues)
        run: |
          if ./target/release/foxguard tests/fixtures/ 2>&1; then
            echo "::error::Expected foxguard to find issues in test fixtures but it exited clean"
            exit 1
          else
            echo "Fixtures correctly detected — foxguard found issues as expected"
          fi
