# Pareidolia developer workflow recipes.
#
# All CI lanes call these recipes by name. Keep them portable so contributors
# can run the exact same commands locally that CI runs.

# Cargo flags appended to most build/test commands. Empty locally (so the
# devShell exercises every default-on feature, including v4l2), but CI sets
# the `CARGO_ARGS` env var to `--no-default-features` because its Nixery
# image doesn't ship libv4l / libclang / kernel headers.
cargo_args := env_var_or_default("CARGO_ARGS", "")

# Show available recipes.
default:
    @just --list

# === Pre-push convenience =====================================================

# Everything a developer should run before pushing. Equivalent to ci-fast +
# ci-slow combined — every check that doesn't require physical hardware.
# Run `just test-hardware` separately if you've touched a hardware-facing
# module and have the devices to exercise it.
test: ci-fast ci-slow

# === Fast lane (runs on every push) ===========================================

# Format check, no writes.
fmt-check:
    cargo fmt --all -- --check

# Clippy with warnings as errors.
lint:
    cargo clippy --workspace --all-targets {{cargo_args}} -- -D warnings

# Unit tests only — every crate's in-source `#[cfg(test)]` blocks.
# Excludes the integration-tests crate to keep this fast.
test-unit:
    cargo nextest run --workspace --lib {{cargo_args}}

# Hardware-dependent tests (marked #[ignore]). Requires real devices on the
# host: a V4L2 camera at /dev/video*, and for the inference tests a model
# file path in PAREIDOLIA_TEST_MODEL.
#
# `--no-capture` makes each test's stderr visible in real time — important
# because individual tests skip with a `warning:` line when their
# prerequisite is missing, and you want to see that.
#
# CI never runs this; it's the developer's responsibility to run locally
# before merging anything that touches a hardware-facing surface.
test-hardware:
    cargo nextest run -p pareidolia-core --features v4l2,inference --run-ignored only --no-capture

# Unit tests with all default-on features enabled. Runs the always-on
# portions of the v4l2 and inference modules without touching hardware.
# Locally only; CI doesn't have libv4l / libonnxruntime configured in its
# Nixery image.
test-features:
    cargo nextest run -p pareidolia-core --features v4l2,inference --lib

# Everything the per-push CI job runs.
ci-fast: fmt-check lint test-unit

# === Slow lane (runs in parallel on push, doesn't block) ======================

# The single integration-test binary.
test-integration:
    cargo nextest run -p pareidolia-integration-tests {{cargo_args}}

# Build all crates in release mode (catches release-only issues like LTO).
build-release:
    cargo build --workspace --release {{cargo_args}}

ci-slow: test-integration build-release

# === Scheduled (runs nightly, not on push) ====================================

# Run mutation tests on critical modules. Surfaces tests that pass even when
# the code is mutated, i.e. tests that don't actually test what they claim.
mutants:
    cargo mutants --in-place \
        --package pareidolia-core \
        --package pareidolia-daemon

# Fuzz each target for 10 minutes.
fuzz:
    @echo "Fuzz targets land alongside the IPC layer (M5). Skipping."

ci-scheduled: mutants fuzz

# === Local-only ===============================================================

# Apply rustfmt.
fmt:
    cargo fmt --all

# Sweep build artifacts older than 14 days.
sweep:
    cargo sweep --time 14

# Hard reset of target/. Use sparingly.
clean:
    cargo clean

# Build everything every CI lane builds. Useful before pushing.
all: ci-fast ci-slow
