name: CI Rust

on:
  workflow_call:

permissions:
  contents: read

jobs:
  # -------------------------------------------------------------------------
  # cargo-deny — uses the official pre-built action (no cargo install needed)
  # -------------------------------------------------------------------------
  cargo-deny:
    name: cargo deny check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: EmbarkStudios/cargo-deny-action@v2

  # -------------------------------------------------------------------------
  # cargo-audit — uses rustsec/audit-check pre-built action
  # -------------------------------------------------------------------------
  cargo-audit:
    name: cargo audit
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: rustsec/audit-check@v2
        with:
          token: ${{ github.token }}

  # -------------------------------------------------------------------------
  # pip-audit + uv.lock freshness check (lightweight, no Rust needed)
  # -------------------------------------------------------------------------
  pip-audit:
    name: pip-audit + uv.lock check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-python@v6
        with:
          python-version: "3.12"
      - run: pip install uv
      - run: uv run --with pip-audit pip-audit --skip-editable
      - run: uv lock --check

  # -------------------------------------------------------------------------
  # fmt + clippy (with Rust cache so subsequent runs skip recompilation)
  # -------------------------------------------------------------------------
  rust-lint:
    name: Rust fmt + clippy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: stable
          components: rustfmt, clippy
      - uses: Swatinem/rust-cache@v2
      - run: cargo fmt --all -- --check
      - run: cargo clippy --release -- -D warnings
      - name: Verify benchmarks compile
        run: cargo bench -p ferro_ta_core --no-run

  # -------------------------------------------------------------------------
  # Build + test ferro_ta_core (with Rust cache)
  # -------------------------------------------------------------------------
  rust-core:
    name: Rust core (build + test)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: stable
      - uses: Swatinem/rust-cache@v2
      - run: cargo build -p ferro_ta_core
      - run: cargo test -p ferro_ta_core

  # -------------------------------------------------------------------------
  # Coverage (optional, cached)
  # -------------------------------------------------------------------------
  rust-coverage:
    name: Rust coverage (tarpaulin)
    runs-on: ubuntu-latest
    continue-on-error: true
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: stable
      - uses: Swatinem/rust-cache@v2
      - uses: taiki-e/install-action@v2
        with:
          tool: cargo-tarpaulin
      - run: cargo tarpaulin -p ferro_ta_core --out Xml --output-dir coverage/
      - uses: actions/upload-artifact@v7
        with:
          name: rust-coverage
          path: coverage/
          if-no-files-found: ignore

  # -------------------------------------------------------------------------
  # Fuzz (optional, nightly, cached)
  # -------------------------------------------------------------------------
  fuzz:
    name: Fuzz targets (short CI run)
    runs-on: ubuntu-latest
    continue-on-error: true
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@v1
        with:
          toolchain: nightly
      - uses: Swatinem/rust-cache@v2
      - uses: taiki-e/install-action@v2
        with:
          tool: cargo-fuzz
      - name: Run fuzz_sma (10000 iterations)
        working-directory: fuzz
        run: cargo fuzz run fuzz_sma -- -runs=10000 -max_len=512
      - name: Run fuzz_rsi (10000 iterations)
        working-directory: fuzz
        run: cargo fuzz run fuzz_rsi -- -runs=10000 -max_len=512
      - uses: actions/upload-artifact@v7
        if: always()
        with:
          name: fuzz-artifacts
          path: fuzz/artifacts/
          if-no-files-found: ignore
