name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]
  workflow_dispatch:

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  # Fast gate — formatting, linting, audit, build
  pre-check:
    name: Pre-flight Checks
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        components: rustfmt, clippy

    - uses: Swatinem/rust-cache@v2

    - name: Check formatting
      run: cargo fmt --all -- --check

    - name: Run clippy
      run: cargo clippy --all-targets --all-features -- -D warnings

    - name: Security audit
      uses: taiki-e/install-action@cargo-audit
    - run: cargo audit

    - name: Build
      run: cargo build --all-features

    - name: Verify tests compile
      run: cargo test --no-run --all-features

  # Tests across OS and Rust versions
  test:
    name: Test (${{ matrix.os }}, ${{ matrix.rust }})
    runs-on: ${{ matrix.os }}
    needs: pre-check
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            rust: stable
          - os: ubuntu-latest
            rust: nightly
          - os: macos-latest
            rust: stable
          - os: windows-latest
            rust: stable
    steps:
    - uses: actions/checkout@v4

    - name: Install Rust ${{ matrix.rust }}
      uses: dtolnay/rust-toolchain@master
      with:
        toolchain: ${{ matrix.rust }}

    - uses: Swatinem/rust-cache@v2

    - name: Install nextest
      uses: taiki-e/install-action@nextest

    - name: Run unit tests
      run: cargo nextest run --lib --all-features

    - name: Run integration tests
      run: cargo nextest run --tests --all-features

    - name: Run doc tests
      run: cargo test --doc --all-features

  # Property-based tests (run on nightly for completeness)
  property-tests:
    name: Property & Fuzz Tests
    runs-on: ubuntu-latest
    needs: pre-check
    steps:
    - uses: actions/checkout@v4

    - name: Install Rust nightly
      uses: dtolnay/rust-toolchain@nightly

    - uses: Swatinem/rust-cache@v2

    - name: Run property-based tests
      run: cargo test --test property_tests -- --nocapture

    - name: Run lib property tests
      run: cargo test --lib property_tests -- --nocapture

  # Cross-compile check for aarch64-linux (using zigbuild, no Docker)
  cross-compile:
    name: Cross-compile (aarch64-linux)
    runs-on: ubuntu-latest
    needs: pre-check
    steps:
    - uses: actions/checkout@v4

    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        targets: aarch64-unknown-linux-gnu

    - uses: Swatinem/rust-cache@v2

    - name: Install zigbuild
      uses: taiki-e/install-action@cargo-zigbuild

    - name: Install Zig
      uses: mlugg/setup-zig@v2

    - name: Build for aarch64-linux
      run: cargo zigbuild --target aarch64-unknown-linux-gnu --all-features

  # Documentation build and doc tests
  docs:
    name: Documentation
    runs-on: ubuntu-latest
    needs: pre-check
    steps:
    - uses: actions/checkout@v4

    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable

    - uses: Swatinem/rust-cache@v2

    - name: Build docs
      run: cargo doc --all-features --no-deps

    - name: Doc tests
      run: cargo test --doc --all-features

  # Benchmarks (only on push to main, not PRs)
  benchmarks:
    name: Benchmarks
    runs-on: ubuntu-latest
    needs: pre-check
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    steps:
    - uses: actions/checkout@v4

    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable

    - uses: Swatinem/rust-cache@v2

    - name: Run benchmarks
      run: cargo bench --all-features

    - name: Archive results
      uses: actions/upload-artifact@v4
      with:
        name: benchmark-results
        path: target/criterion/
        retention-days: 14
