use anyhow::Result;
use clap::Parser;
use tracing_subscriber::EnvFilter;

use stemedb_admin::{
    cli::{Cli, ClusterCommands, Commands, DebugCommands, NodeCommands, ShardCommands},
    client::AdminClient,
    commands,
};

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

    // Initialize logging
    let filter = if cli.verbose {
        EnvFilter::new("stemedb_admin=debug")
    } else {
        EnvFilter::new("stemedb_admin=info")
    };

    tracing_subscriber::fmt().with_env_filter(filter).with_target(false).without_time().init();

    // Create admin client
    let client = AdminClient::new(cli.gateway);

    // Execute command
    match cli.command {
        Commands::Cluster { cmd } => match cmd {
            ClusterCommands::Status => {
                commands::cluster::cluster_status(&client, cli.format).await?
            }
            ClusterCommands::Health => {
                commands::cluster::cluster_health(&client, cli.format).await?
            }
        },
        Commands::Node { cmd } => match cmd {
            NodeCommands::List => commands::node::list_nodes(&client, cli.format).await?,
            NodeCommands::Info { node_id } => {
                commands::node::node_info(&client, &node_id, cli.format).await?
            }
            NodeCommands::Shards { node_id, leader } => {
                commands::node::node_shards(&client, &node_id, leader, cli.format).await?
            }
        },
        Commands::Shard { cmd } => match cmd {
            ShardCommands::List => commands::shard::list_shards(&client, cli.format).await?,
            ShardCommands::Info { shard_id } => {
                commands::shard::shard_info(&client, shard_id, cli.format).await?
            }
            ShardCommands::Replicas { shard_id } => {
                commands::shard::shard_replicas(&client, shard_id, cli.format).await?
            }
        },
        Commands::Debug { cmd } => match cmd {
            DebugCommands::Export { output } => {
                commands::debug::export_debug_state(&client, &output).await?
            }
        },
    }

    Ok(())
}
