use anyhow::Result;
use clap::Parser;
use ethl_cli::commands::{
    Commands, ProviderArgs, cat::run_cat_command, extract::extract_events,
    merge::run_merge_command, repair::run_repair_command,
};
use tracing::debug;

#[derive(Debug, Parser)]
#[command(name = "ethlogs")]
#[command(version)]
#[command(about = "Ethereum event stream utilitites", long_about = None)]
struct Cli {
    #[command(subcommand)]
    command: Commands,

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

    /// Common provider configuration for all commands
    #[command(flatten)]
    provider_args: ProviderArgs,
}

fn setup_logging(verbose: bool) -> Result<()> {
    let mut filter = tracing_subscriber::EnvFilter::from_default_env()
        .add_directive(tracing::Level::INFO.into());

    if verbose {
        filter = filter
            .add_directive("ethl=debug".parse()?)
            .add_directive("ethl_cli=debug".parse()?);
    }

    tracing_subscriber::fmt().with_env_filter(filter).init();

    Ok(())
}

#[tokio::main]
async fn main() -> Result<()> {
    dotenvy::dotenv().ok();
    let args = Cli::parse();
    setup_logging(args.verbose)?;

    let providers = args.provider_args.try_into()?;
    debug!("Using providers: {:?}", providers);

    match args.command {
        Commands::Extract(args) => {
            extract_events(&providers, args).await?;
        }
        Commands::Cat(args) => {
            run_cat_command(&providers, args).await?;
        }
        Commands::Merge(args) => {
            run_merge_command(args).await?;
        }
        Commands::Repair(args) => {
            run_repair_command(args).await?;
        }
    }

    Ok(())
}
