mod baseline;
mod calibrate;
mod check;
mod classify;
mod init;
mod mcp;
mod report;
mod review;
mod sarif;
mod scan;

use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command(
    name = "diffsift",
    version,
    about = "Classify code changes by semantic impact"
)]
struct Cli {
    #[command(subcommand)]
    command: Commands,

    /// Suppress non-essential output
    #[arg(long, global = true)]
    quiet: bool,

    /// Enable verbose output
    #[arg(long, global = true)]
    verbose: bool,
}

#[derive(Subcommand)]
enum Commands {
    /// Classify hunks in a diff by semantic category and priority
    Classify(classify::ClassifyArgs),

    /// Review a PR: classify, call LLM, and post comments
    Review(review::ReviewArgs),

    /// Initialize .diffsift/config.toml in a repository
    Init(init::InitArgs),

    /// Scan git history and classify past commits
    #[command(alias = "history")]
    Scan(scan::ScanArgs),

    /// Create a baseline snapshot of known findings
    Baseline(baseline::BaselineArgs),

    /// Validate .diffsift/ configuration and custom rules
    Check(check::CheckArgs),

    /// Calibrate rule weights from GitHub PR comment reactions (👍/👎)
    Calibrate(calibrate::CalibrateArgs),

    /// Generate a review quality report from calibration data
    Report(report::ReportArgs),

    /// Start an MCP (Model Context Protocol) server for AI agent integration
    Mcp(mcp::McpArgs),
}

#[tokio::main]
async fn main() -> miette::Result<()> {
    let cli = Cli::parse();

    let filter = if cli.verbose {
        "debug"
    } else if cli.quiet {
        "warn"
    } else {
        "info"
    };

    tracing_subscriber::fmt()
        .with_env_filter(
            tracing_subscriber::EnvFilter::try_from_default_env()
                .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new(filter)),
        )
        .with_writer(std::io::stderr)
        .init();

    match cli.command {
        Commands::Classify(args) => classify::run(args),
        Commands::Review(args) => review::run(args).await,
        Commands::Init(args) => init::run(args),
        Commands::Scan(args) => scan::run(args),
        Commands::Baseline(args) => baseline::run(args),
        Commands::Check(args) => check::run(args),
        Commands::Calibrate(args) => calibrate::run(args).await,
        Commands::Report(args) => report::run(args),
        Commands::Mcp(args) => mcp::run(args),
    }
}
