use std::{env, path::Path, process::ExitCode};

fn main() -> ExitCode {
    let mut args = env::args().skip(1).collect::<Vec<_>>();
    if args.is_empty() {
        eprintln!("usage: muga [check|run] <source-file>");
        return ExitCode::from(2);
    }

    let (mode, path) = if args.len() >= 2 && matches!(args[0].as_str(), "check" | "run") {
        (args.remove(0), args.remove(0))
    } else {
        ("run".to_string(), args.remove(0))
    };

    match mode.as_str() {
        "check" => match muga::check_path(Path::new(&path)) {
            Ok(_) => {
                println!("ok");
                ExitCode::SUCCESS
            }
            Err(diagnostics) => {
                for diagnostic in diagnostics {
                    eprintln!("{diagnostic}");
                }
                ExitCode::from(1)
            }
        },
        "run" => match muga::run_path(Path::new(&path)) {
            Ok(outcome) => {
                let has_output = !outcome.output_text.is_empty();
                if has_output {
                    print!("{}", outcome.output_text);
                }
                if let Some(value) = outcome.main_result {
                    if has_output && !outcome.output_text.ends_with('\n') {
                        println!();
                    }
                    println!("{value}");
                } else {
                    if has_output && !outcome.output_text.ends_with('\n') {
                        println!();
                    }
                    println!("ok");
                }
                ExitCode::SUCCESS
            }
            Err(diagnostics) => {
                for diagnostic in diagnostics {
                    eprintln!("{diagnostic}");
                }
                ExitCode::from(1)
            }
        },
        _ => {
            eprintln!("usage: muga [check|run] <source-file>");
            ExitCode::from(2)
        }
    }
}
