mod run_command;
mod benchmark_command;
mod print_command;
mod report_command;
mod ls_command;
mod version_command;
mod node_utils;

use clap::{Parser, Subcommand};

#[derive(Parser)]
#[command(name = "aqua", about = "load testing tool for solana rpc endpoints", version)]
pub struct Cli {
    #[command(subcommand)]
    pub command: Option<Commands>,

    #[arg(global = true, long)]
    pub debug: bool,
}

#[derive(Subcommand)]
pub enum Commands {
    #[command(about = "run a load test")]
    Run(run_command::RunArgs),
    #[command(about = "benchmark two geyser endpoints")]
    Benchmark(benchmark_command::BenchmarkArgs),
    #[command(about = "print results from previous test")]
    Print(print_command::PrintArgs),
    #[command(about = "generate report from test results")]
    Report(report_command::ReportArgs),
    #[command(about = "list available methods")]
    Ls,
    #[command(about = "show version")]
    Version,
}

pub fn run_cli() {
    let cli = Cli::parse();
    let rt = tokio::runtime::Runtime::new().expect("failed to create runtime");

    let result = rt.block_on(async {
        match cli.command {
            Some(Commands::Run(args)) => run_command::run(args).await,
            Some(Commands::Benchmark(args)) => benchmark_command::run(args).await,
            Some(Commands::Print(args)) => print_command::run(args),
            Some(Commands::Report(args)) => report_command::run(args),
            Some(Commands::Ls) => { ls_command::run(); Ok(()) }
            Some(Commands::Version) => { version_command::run(); Ok(()) }
            None => { println!("use --help for usage"); Ok(()) }
        }
    });

    if let Err(e) = result {
        eprintln!("error: {}", e);
        std::process::exit(1);
    }
}
