//! Arguments for `mcptest security redteam`.

use clap::{Args, ValueEnum};

/// Drive the Layer C1 red-team corpus against a live MCP server and report
/// per-model exploitability.
///
/// The command connects to `--url`, runs each scenario through the agent loop
/// driving `--model`, and scores the captured trace with the deterministic
/// observable-evidence oracle. The result is an ADVISORY per-model
/// exploitability signal (ADR 0041): it never becomes the process verdict, so
/// the exit code reflects whether the run completed, not whether the model was
/// exploitable.
///
/// Custom connection headers come from the global `--header` / `--header-env`
/// flags, so a credential never rides a red-team-specific flag.
#[derive(Debug, Args)]
pub struct RedteamArgs {
    /// Streamable HTTP URL of the MCP server under test. The corpus assumes a
    /// poisoned or attacker-influenced server, so point this at a server you
    /// are deliberately probing.
    #[arg(long)]
    pub url: String,

    /// Model id under test (for example `claude-sonnet-4-5`). The model is the
    /// target, not a judge. The provider is resolved from the environment the
    /// same way agent runs resolve it; the API key is never logged.
    #[arg(long)]
    pub model: String,

    /// Output format for the exploitability report.
    #[arg(long, value_enum, default_value_t = RedteamFormat::Pretty)]
    pub format: RedteamFormat,

    /// Hard cap on agent tool-use iterations per scenario. Keeps a runaway
    /// model from looping a tool forever and bounds real model spend.
    #[arg(long, default_value_t = 6)]
    pub max_turns: u32,

    /// Per-call `max_tokens` for the model under test.
    #[arg(long, default_value_t = 512)]
    pub max_tokens: u32,

    /// Run the Layer C2 adaptive campaign instead of the fixed C1
    /// corpus. The adaptive lane mutates each attack seed through a converter
    /// ladder (leetspeak, ROT13, homoglyphs, hex) and stops at the first
    /// variant that exploits the model. The exploitability signal is still
    /// advisory only (ADR 0041): it never changes the exit code.
    #[arg(long)]
    pub adaptive: bool,

    /// Cap on converter attempts per seed in the adaptive lane (`--adaptive`).
    /// Bounds real model spend so a campaign cannot run the whole ladder for
    /// every seed. 0 means use the whole ladder. Ignored without `--adaptive`.
    #[arg(long, default_value_t = 0)]
    pub max_attempts: usize,

    /// Corpus selector. The OSS binary always runs the base corpus;
    /// `premium` and `all` are reserved for the enterprise build
    /// (`mcptest-ee`), which links the
    /// `mcptest-security-corpus` crate. The OSS binary accepts the
    /// flag (so a workflow does not have to rewrite the command line
    /// when switching builds), prints a one-line stderr notice when
    /// `premium` or `all` is requested, and falls back to base.
    #[arg(long, value_enum, default_value_t = CorpusSelection::Base)]
    pub corpus: CorpusSelection,
}

/// Which corpus the red-team lane should run.
///
/// Mirrors the enterprise `mcptest_security_corpus::CorpusSelection`
/// wire shape so a workflow that flips the binary from `mcptest` to
/// `mcptest-ee` does not have to change its command line. The OSS
/// build understands every variant for argument parsing; the
/// handler enforces the OSS floor by treating non-base values as
/// "premium content is enterprise-only" and falling back to base.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, ValueEnum)]
pub enum CorpusSelection {
    /// The OSS base corpus. Always available; the OSS-floor policy.
    #[default]
    Base,
    /// The enterprise premium curated corpus. OSS-only build falls
    /// back to `Base` with a one-line stderr notice.
    Premium,
    /// Base + premium. OSS-only build falls back to `Base` with a
    /// one-line stderr notice.
    All,
}

/// How the per-model exploitability report is rendered.
///
/// Both formats label the output a per-model signal, never a security grade,
/// so a reader cannot mistake an exploitability rate for the server's verdict.
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum RedteamFormat {
    /// Human-readable per-model summary.
    Pretty,
    /// Machine-readable JSON of the [`mcptest_core::security::ModelExploitability`]
    /// report.
    Json,
}
