name: CI

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

env:
  CARGO_TERM_COLOR: always
  RUSTFLAGS: "-D warnings"

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

  clippy:
    name: clippy --all-features
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy
      - uses: Swatinem/rust-cache@v2
      - run: cargo clippy --all-targets --all-features -- -D warnings

  test:
    name: test (${{ matrix.features }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        features:
          - "default"
          - "serde"
          - "parallel"
          - "serde,parallel"
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - name: Run unit + integration + property tests
        run: |
          if [ "${{ matrix.features }}" = "default" ]; then
            cargo test
          else
            cargo test --features ${{ matrix.features }}
          fi
      - name: Run doctests
        run: |
          if [ "${{ matrix.features }}" = "default" ]; then
            cargo test --doc
          else
            cargo test --doc --features ${{ matrix.features }}
          fi

  doc:
    name: cargo doc
    runs-on: ubuntu-latest
    env:
      RUSTDOCFLAGS: "-D warnings"
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - run: cargo doc --no-deps --all-features

  msrv:
    name: minimum supported Rust version (1.85)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@1.85
      - uses: Swatinem/rust-cache@v2
      - run: cargo build --all-features

  fuzz:
    name: fuzz smoke (${{ matrix.target }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        target:
          - pareto_compare
          - non_dominated_sort
          - hypervolume_2d
          - pareto_archive
          - crowding_distance
          - spacing
          - sbx_polymut
          - clamp_to_bounds
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@nightly
      - uses: Swatinem/rust-cache@v2
        with:
          workspaces: fuzz -> target
      - name: Install cargo-fuzz
        # No `--locked`: cargo-fuzz's bundled Cargo.lock pins
        # rustix=0.36.5, which uses the now-removed `rustc_attrs` cfg
        # name and fails to build on current nightly. Letting cargo
        # resolve fresh picks a recent rustix that builds cleanly.
        run: cargo install cargo-fuzz
      - name: 60-second soak
        run: cargo fuzz run ${{ matrix.target }} -- -max_total_time=60
