name: CI

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

jobs:
  dotrepo:
    name: dotrepo
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

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

      - name: Install dotrepo
        run: cargo install --git https://github.com/maxwellsantoro/dotrepo dotrepo-cli --locked

      - name: Validate manifest
        run: dotrepo validate

      - name: Check generated surfaces
        run: dotrepo generate --check

  release-integrity:
    name: Release Integrity
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      - name: Setup Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.11'

      - name: Check release metadata integrity
        run: python3 scripts/check_release_integrity.py

  fmt:
    name: Format
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      - name: Setup Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt

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

  clippy:
    name: Clippy
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      - name: Setup Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          components: clippy

      - name: Cache cargo registry
        uses: Swatinem/rust-cache@v2

      - name: Install dependencies for rug (GMP/MPFR)
        run: sudo apt-get update && sudo apt-get install -y libgmp-dev libmpfr-dev

      - name: Run clippy (default features)
        run: cargo clippy --all-targets --locked -- -D warnings

      - name: Run clippy (no default features)
        run: cargo clippy --all-targets --no-default-features --locked -- -D warnings

      - name: Run clippy (highprec feature)
        run: cargo clippy --all-targets --features highprec --locked -- -D warnings

  check-features:
    name: Feature coverage check
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

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

      - name: Cache cargo registry
        uses: Swatinem/rust-cache@v2

      - name: Setup Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.11'

      - name: Check Python bindings crate
        run: cargo check --manifest-path ries-py/Cargo.toml --locked

      - name: Build wasm feature
        run: cargo build --features wasm --locked

      - name: Build wasm + parallel features
        run: cargo build --features "wasm parallel" --locked

  test-ries-py-rust:
    name: Test (ries-py Rust helpers)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

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

      - name: Setup Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.11'

      - name: Cache cargo registry
        uses: Swatinem/rust-cache@v2

      - name: Run ries-py Rust-side tests
        run: ./scripts/test_ries_py_rust.sh

  test-ries-py-python:
    name: Test (ries-py Python integration)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

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

      - name: Setup Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.11'

      - name: Setup uv
        uses: astral-sh/setup-uv@v5

      - name: Cache cargo registry
        uses: Swatinem/rust-cache@v2

      - name: Run ries-py Python integration tests
        run: ./scripts/test_ries_py_python.sh -q

  test:
    name: Test (${{ matrix.os }})
    runs-on: ${{ matrix.os }}
    env:
      CARGO_PROFILE_TEST_DEBUG: 0
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    steps:
      - name: Checkout
        uses: actions/checkout@v5

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

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

      - name: Cache cargo registry
        uses: Swatinem/rust-cache@v2

      - name: Run tests
        run: cargo nextest run --tests --locked

  test-highprec:
    name: Test (highprec feature)
    runs-on: ubuntu-latest
    env:
      CARGO_PROFILE_TEST_DEBUG: 0
    steps:
      - name: Checkout
        uses: actions/checkout@v5

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

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

      - name: Cache cargo registry
        uses: Swatinem/rust-cache@v2

      - name: Install dependencies for rug (GMP/MPFR)
        run: sudo apt-get update && sudo apt-get install -y libgmp-dev libmpfr-dev

      - name: Run tests with highprec feature
        run: cargo nextest run --tests --features highprec --locked

  test-wasm:
    name: Test (WASM)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      - name: Setup Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: wasm32-unknown-unknown

      - name: Install wasm-pack
        run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

      - name: Run WASM tests
        run: wasm-pack test --node -- --features wasm

  audit:
    name: Security Audit
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

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

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

      - name: Run security audit
        run: cargo audit

  parity-check:
    name: Parity Check (Original RIES)
    runs-on: ubuntu-latest
    steps:
      - name: Checkout ries-rs
        uses: actions/checkout@v5

      - name: Detect bundled original RIES source
        id: has-original
        run: |
          if [ -f ries-original/ries.c ]; then
            echo "present=true" >> "$GITHUB_OUTPUT"
          else
            echo "present=false" >> "$GITHUB_OUTPUT"
            echo "ries-original/ries.c not found; skipping parity-check job steps."
          fi

      - name: Setup C Compiler
        if: steps.has-original.outputs.present == 'true'
        run: sudo apt-get update && sudo apt-get install -y gcc

      - name: Compile Original RIES
        if: steps.has-original.outputs.present == 'true'
        run: gcc ries-original/ries.c -lm -o ries-original/ries

      - name: Setup Rust
        if: steps.has-original.outputs.present == 'true'
        uses: dtolnay/rust-toolchain@stable

      - name: Cache cargo registry
        if: steps.has-original.outputs.present == 'true'
        uses: Swatinem/rust-cache@v2

      - name: Build ries-rs
        if: steps.has-original.outputs.present == 'true'
        run: cargo build --release

      - name: Run Parity Checks
        if: steps.has-original.outputs.present == 'true'
        run: |
          chmod +x tests/compare_with_original.sh
          # Test Pi
          ./tests/compare_with_original.sh 3.1415926535 2 6 ./ries-original/ries
          # Test e
          ./tests/compare_with_original.sh 2.7182818284 2 6 ./ries-original/ries
          # Test Golden Ratio
          ./tests/compare_with_original.sh 1.6180339887 2 6 ./ries-original/ries
