#[cfg(not(target_family = "wasm"))]
use rudof_cli::{
    cli::parser::{Cli, Command},
    commands::{CommandContext, CommandFactory},
};
#[cfg(not(target_family = "wasm"))]
use std::env;

#[cfg(target_family = "wasm")]
fn main() {}

#[cfg(not(target_family = "wasm"))]
fn main() -> std::process::ExitCode {
    // Initialize logging, environment variables, and global settings
    setup();

    match run() {
        Ok(()) => std::process::ExitCode::SUCCESS,
        Err(err) => {
            // Not `{err:?}` (anyhow's default `Termination` formatting for a
            // bare `fn main() -> anyhow::Result<()>`, which this replaces):
            // several of this crate's error types already embed their full
            // wrapped-cause text into their own `Display`, which anyhow's
            // "walk `source()` and print every link" default then repeats a
            // second time. `format_error` prints each genuinely new piece
            // of information once, on its own line.
            eprintln!(
                "{} {}",
                rudof_cli::output::error_prefix(),
                rudof_cli::output::format_error(&err)
            );
            std::process::ExitCode::FAILURE
        },
    }
}

#[cfg(not(target_family = "wasm"))]
fn run() -> anyhow::Result<()> {
    use clap::Parser;

    // Use args_os to safely handle non-UTF8 paths/arguments from the system
    let args = clientele::args_os()?;
    let cli = Cli::parse_from(args);

    // Dispatch the command if present, otherwise exit with a clean error message
    match &cli.command {
        Some(cmd) => execute(cmd, cli.debug)?,
        None => anyhow::bail!("Command not specified. Use --help for available commands."),
    }

    Ok(())
}

#[cfg(not(target_family = "wasm"))]
/// Sets up the application environment including logging and signal handling.
fn setup() {
    clientele::dotenv().ok();

    unsafe {
        env::set_var("RUSTEMO_NOTRACE", "1");
    }

    rudof_cli::logging::init();
}

#[cfg(not(target_family = "wasm"))]
/// Orchestrates the command lifecycle: Creation -> Validation -> Execution.
fn execute(cli_command: &Command, debug: u8) -> anyhow::Result<()> {
    // Convert CLI enum into a Command Trait Object
    let command = CommandFactory::create(cli_command.clone())?;

    // Prepare the execution context (writers, colors, config)
    let mut ctx = CommandContext::from_cli(cli_command, debug)?;

    // Run the core logic
    command.execute(&mut ctx)?;

    Ok(())
}
