//! Arguments for `mcptest report`.

use std::path::PathBuf;

use clap::{Args, ValueEnum};

/// Arguments for `mcptest report`.
///
/// Takes a previously-saved JSON `Report` and re-renders it in another
/// format. Saves a re-run when CI already captured the JSON but a different
/// reporter is wanted after the fact.
#[derive(Debug, Args)]
pub struct ReportArgs {
    /// Path to a JSON report previously written by `mcptest run`.
    pub input: PathBuf,

    /// Reporter format to render in.
    #[arg(
        long,
        value_enum,
        value_name = "FORMAT",
        default_value_t = ReportFormat::Pretty
    )]
    pub format: ReportFormat,

    /// Write to this file instead of stdout.
    #[arg(long, value_name = "PATH")]
    pub output: Option<PathBuf>,

    /// Overwrite `--output` if it already exists (off by default so a re-run
    /// cannot silently clobber a tracked or hand-edited file).
    #[arg(long)]
    pub force: bool,

    /// Collector flags for `--format upload`.
    #[command(flatten)]
    pub upload: UploadArgs,
}

/// Collector flags consumed by `mcptest report --format upload`.
///
/// Scoped to the report subcommand (not global) because no other command
/// uploads anything. Collectors are typically a hosted aggregation service
/// (an mcptest-cloud instance or an internal observability endpoint).
#[derive(Debug, Args, Default)]
pub struct UploadArgs {
    /// Endpoint to POST the canonical run envelope to.
    ///
    /// Only read by `--format upload`. The body shape is documented in
    /// `schemas/wire/v0.json`. Combine with `--upload-token-env` when the
    /// collector requires a bearer token.
    #[arg(long = "upload-endpoint", value_name = "URL")]
    pub upload_endpoint: Option<String>,

    /// Name of the env var that holds the bearer token for the upload
    /// reporter. Read at config-build time and sent verbatim as
    /// `Authorization: Bearer <value>`.
    #[arg(long = "upload-token-env", value_name = "NAME")]
    pub upload_token_env: Option<String>,

    /// Optional organization tag included in the upload envelope, for
    /// collectors that attribute runs to an organization.
    #[arg(long = "upload-organization", value_name = "NAME")]
    pub upload_organization: Option<String>,
}

/// Output formats accepted by `mcptest report --format`.
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, ValueEnum)]
#[value(rename_all = "kebab-case")]
pub enum ReportFormat {
    /// Human-friendly text output (default).
    #[default]
    Pretty,
    /// Pretty-printed JSON (round-trippable through the same model).
    Json,
    /// JUnit XML suitable for `dorny/test-reporter` and CircleCI Insights.
    Junit,
    /// GitHub-flavored Markdown for PR comments and job summaries.
    Md,
    /// Single-file HTML report with inline CSS.
    Html,
    /// SARIF 2.1.0 for GitHub code-scanning and similar consumers.
    Sarif,
    /// GitLab Code Quality JSON for merge request widgets.
    Gitlab,
    /// Newline-delimited JSON, one record per line, for log pipelines.
    Ndjson,
    /// Test Anything Protocol v14, for prove/tappy-style consumers.
    Tap,
    /// Comparison-matrix grid (test x model) as a self-contained HTML file.
    Matrix,
    /// Comparison-matrix grid as GitHub-flavored Markdown.
    MatrixMd,
    /// Compact, model-facing output for a coding agent reading the result.
    Agent,
    /// OpenInference / OTLP-compatible trace spans as JSONL, for eval and
    /// observability platforms.
    Openinference,
    /// HTTPS upload of the canonical run envelope to the endpoint passed
    /// via `--upload-endpoint`.
    Upload,
}

impl ReportFormat {
    /// Map to the shared [`RenderFormat`](crate::cli::reporters::RenderFormat),
    /// or `None` for `upload` (a network push, not a rendered format).
    pub(crate) fn render_format(self) -> Option<crate::cli::reporters::RenderFormat> {
        use crate::cli::reporters::RenderFormat;
        Some(match self {
            ReportFormat::Pretty => RenderFormat::Pretty,
            ReportFormat::Json => RenderFormat::Json,
            ReportFormat::Junit => RenderFormat::Junit,
            ReportFormat::Md => RenderFormat::Md,
            ReportFormat::Html => RenderFormat::Html,
            ReportFormat::Sarif => RenderFormat::Sarif,
            ReportFormat::Gitlab => RenderFormat::Gitlab,
            ReportFormat::Ndjson => RenderFormat::Ndjson,
            ReportFormat::Tap => RenderFormat::Tap,
            ReportFormat::Matrix => RenderFormat::Matrix,
            ReportFormat::MatrixMd => RenderFormat::MatrixMd,
            ReportFormat::Agent => RenderFormat::Agent,
            ReportFormat::Openinference => RenderFormat::Openinference,
            ReportFormat::Upload => return None,
        })
    }
}
