//! A Radicle CI adapter for native CI.
//!
//! Perform the CI run locally, without any isolation. This is not
//! safe and secure, but it's simple, and easy to get working. Do not
//! use this unless you trust the repository.
//!
//! The repository must contain a file `.radicle/native.yaml` that
//! specifies how CI is run for the repository. For example:
//!
//! ```yaml
//! shell: |
//!   cargo test --locked --workspace
//! ```

#![allow(clippy::result_large_err)]

use std::{env::args, error::Error, process::exit};

use radicle_native_ci::engine::{Engine, EngineError};

// Exit codes for the program.
const EXIT_OK: i32 = 0;
const EXIT_FAILURE: i32 = 1;
const EXIT_ERROR: i32 = 2;

/// The main program.
fn main() {
    let code = match fallible_main() {
        Ok(success) => {
            if success {
                EXIT_OK
            } else {
                EXIT_FAILURE
            }
        }
        Err(e) => {
            eprintln!("ERROR: {e}");
            let mut e = e.source();
            while let Some(source) = e {
                eprintln!("caused by: {source}");
                e = source.source();
            }
            EXIT_ERROR
        }
    };
    exit(code);
}

fn fallible_main() -> Result<bool, EngineError> {
    let args: Vec<String> = args().skip(1).collect();

    if args.is_empty() {
        let mut engine = Engine::new()?;
        engine.run()
    } else {
        for arg in args.iter() {
            match arg.as_str() {
                "--version" => println!("{} {}", env!("CARGO_PKG_NAME"), env!("VERSION")),
                "--show-config" => {
                    let engine = Engine::new()?;
                    println!("{}", engine.config().as_json());
                }
                _ => {
                    eprintln!("unknown argument {arg}");
                    return Ok(false);
                }
            }
        }
        Ok(true)
    }
}
