use std::process::ExitCode;

use rdbms_playground::cli::{Args, help_text, version_text};
use rdbms_playground::{logging, runtime};

fn main() -> ExitCode {
    // ADR-0019 §8.6: parse the embedded message catalog up
    // front so a corrupted build artefact fails loudly here
    // rather than at the first `t!()` call deep inside the
    // event loop. Cheap — the catalog is small and `OnceLock`
    // memoises the parse for every subsequent caller.
    // Doing this first also means the args-parse error path
    // below can pull `help.cli_banner` from the catalog.
    let _ = rdbms_playground::friendly::catalog();

    let args = match Args::from_env() {
        Ok(args) => args,
        Err(e) => {
            eprintln!("rdbms-playground: {e}");
            eprintln!("\n{}", help_text());
            return ExitCode::from(2);
        }
    };

    if args.version {
        println!("{}", version_text());
        return ExitCode::SUCCESS;
    }

    if args.help {
        print!("{}", help_text());
        return ExitCode::SUCCESS;
    }

    if let Err(e) = logging::init(args.log_path.as_deref()) {
        eprintln!("rdbms-playground: failed to initialise logging: {e:#}");
        return ExitCode::FAILURE;
    }

    let tokio_rt = match tokio::runtime::Runtime::new() {
        Ok(rt) => rt,
        Err(e) => {
            tracing::error!(error = %e, "failed to start tokio runtime");
            return ExitCode::FAILURE;
        }
    };

    match tokio_rt.block_on(runtime::run(args)) {
        Ok(()) => ExitCode::SUCCESS,
        Err(e) => {
            tracing::error!(error = %e, "runtime exited with error");
            eprintln!("rdbms-playground: {e:#}");
            ExitCode::FAILURE
        }
    }
}
