//! Instruction-counting benchmarks for the `grund` CLI — see
//! `docs/architecture/AR-benchmarks.md`.
//!
//! Each benchmark runs the freshly built `grund` binary under Callgrind via
//! `iai-callgrind`, so the reported figure is the deterministic instruction
//! count for an actual CLI invocation against this repository's conformant
//! tree. Instruction counts (unlike wall-clock time) do not flake on a loaded
//! CI runner, which is what makes "track the number across commits and fail on
//! regression" implementable — the meter the GOAL-fast-feedback budget asks for.
//!
//! The benched subcommands are the ones agents and CI invoke on every loop:
//!
//! - `check` — every save / commit / push; the headline operation.
//! - `list` / `show --brief` / `show` / `show --full` / `refs` — the agent
//!   grounding workflow (discover IDs, preview the title plus first paragraph,
//!   read the lead-default slice, escalate to a full declaration body, see a
//!   declaration's blast radius).
//! - `cover` — what the co-change recipe / CI consume.
//! - `fmt --check` — the pre-commit / CI normalization gate.
//!
//! Each command exits 0 on this repository's conformant tree, so iai-callgrind
//! (which expects `ExitWith::Success`) is happy. On a *broken* tree — a dangling
//! citation, a stray `$$` trigger — `check` / `fmt --check` exit non-zero and
//! the bench fails; that is intentional, not a bug to paper over with
//! `.exit_with(...)`: a baseline recorded against a broken tree is worthless.
//!
//! The same workload drives the release/benchmark PGO training run in
//! `scripts/pgo-build.sh` (§DA-pgo-release) — keep the command list there in
//! sync with this file.
//!
//! Run with `cargo bench --features bench` (requires Valgrind and
//! `iai-callgrind-runner` on `PATH`; CI installs both — see
//! `.github/workflows/ci.yml`). Without the `bench` feature this target builds
//! to a no-op `main`, so `cargo test --all-targets` never needs Valgrind.

#[cfg(feature = "bench")]
use iai_callgrind::{Command, binary_benchmark, binary_benchmark_group, main};

/// The freshly built `grund` binary under test (Cargo exports this env var).
#[cfg(feature = "bench")]
const GRUND: &str = env!("CARGO_BIN_EXE_grund");
/// This repository's root — the conformant tree every benchmark scans, matching
/// the `grund .` self-host loop CI already runs.
#[cfg(feature = "bench")]
const REPO: &str = env!("CARGO_MANIFEST_DIR");

/// A representative declared ID with a substantial body — enough to exercise
/// the brief preview, lead-default read, and full recursive body in the show
/// ladder when an agent grounds itself before editing.
#[cfg(feature = "bench")]
const SHOW_ID: &str = "FS-check";
/// A heavily-cited goal — `grund refs` over it walks the whole tree and returns
/// the blast radius an agent checks before changing a declaration.
#[cfg(feature = "bench")]
const REFS_ID: &str = "GOAL-fast-feedback";

// `grund check <repo>` — validate every citation in the tree.
#[cfg(feature = "bench")]
#[binary_benchmark]
fn check() -> Command {
    Command::new(GRUND).args(["check", REPO]).build()
}

// `grund list <repo>` — every declared ID.
#[cfg(feature = "bench")]
#[binary_benchmark]
fn list() -> Command {
    Command::new(GRUND).args(["list", REPO]).build()
}

// `grund <ID> --brief <repo>` — title plus first paragraph.
#[cfg(feature = "bench")]
#[binary_benchmark]
fn show_brief() -> Command {
    Command::new(GRUND)
        .args(["show", SHOW_ID, "--brief", REPO])
        .build()
}

// `grund <ID> <repo>` — the lead-default declaration read.
#[cfg(feature = "bench")]
#[binary_benchmark]
fn show() -> Command {
    Command::new(GRUND).args(["show", SHOW_ID, REPO]).build()
}

// `grund <ID> --full <repo>` — one full declaration body.
#[cfg(feature = "bench")]
#[binary_benchmark]
fn show_full() -> Command {
    Command::new(GRUND)
        .args(["show", SHOW_ID, "--full", REPO])
        .build()
}

// `grund refs <ID> <repo>` — every citation site of an ID.
#[cfg(feature = "bench")]
#[binary_benchmark]
fn refs() -> Command {
    Command::new(GRUND).args(["refs", REFS_ID, REPO]).build()
}

// `grund cover <repo>` — the citation graph grouped by scanned file.
#[cfg(feature = "bench")]
#[binary_benchmark]
fn cover() -> Command {
    Command::new(GRUND).args(["cover", REPO]).build()
}

// `grund fmt --check <repo>` — report (without writing) any non-canonical citation.
#[cfg(feature = "bench")]
#[binary_benchmark]
fn fmt_check() -> Command {
    Command::new(GRUND).args(["fmt", "--check", REPO]).build()
}

#[cfg(feature = "bench")]
binary_benchmark_group!(
    name = commands;
    benchmarks = check, list, show_brief, show, show_full, refs, cover, fmt_check
);

#[cfg(feature = "bench")]
main!(binary_benchmark_groups = commands);

#[cfg(not(feature = "bench"))]
fn main() {}
