// Stores argc and argv from the original Doom
// M_CheckParm as well as a helper to get a param value (e.g -file MyWad.wad)

use std::sync::OnceLock;

static MYARGC: OnceLock<usize> = OnceLock::new();

static MYARGV: OnceLock<Vec<String>> = OnceLock::new();

pub const PARM_NOT_FOUND: i32 = 0;

pub fn init(args: Vec<String>) {
    MYARGC.set(args.len()).ok();
    MYARGV.set(args).ok();
}

/// Returns the value of the pass CLI arguments at the position specified by `index`
#[allow(non_snake_case)]
pub fn M_GetPositionalArgv() -> Option<&'static str> {
    let args = MYARGV.get()?;

    args.iter()
        .skip(1)
        .find(|arg| {
            !arg.starts_with('-')
        })
        .map(|s| s.as_str())
}

/// Returns the value of a optional argument specified by the argument
/// 
#[allow(non_snake_case)]
pub fn M_GetOptionalArgumentValueByArgument(arg: &str) -> Option<&'static str>  {

    let idx: usize =  M_CheckParm(arg) as usize;

    if idx == 0 {
        return None;
    }

    let argv: &Vec<String> = MYARGV.get()?;
    let idx_val = idx + 1;
    if idx_val > argv.len() - 1 {
        return None
    }
    Some(argv[idx_val].as_str())

}

/// Returns the value of a optional argument specified by the argument
/// 
#[allow(non_snake_case)]
pub fn M_GetOptionalArgumentValueByIndex(index: i32) -> Option<&'static str>  {

    let idx = index as usize;
    if idx == 0 {
        return None;
    }

    let argv: &Vec<String> = MYARGV.get()?;
    let idx_val = idx + 1;
    if idx_val > argv.len() - 1 {
        return None
    }
    Some(argv[idx_val].as_str())

}

/// Checks for the given paramter in the program command line arugments
/// Returns the argument number or zero if not present
#[allow(non_snake_case)]
pub fn M_CheckParm(c_str: &str) -> i32 {

    let args = match MYARGV.get() {
        Some(a) => a,
        None => return 0, // Not initialized yet
    };

    for i in 1..args.len() {
        if args[i] == c_str {
            return i as i32;
        }
    }

    PARM_NOT_FOUND
}

/// Gets all the parameters of myargv
#[allow(non_snake_case)]
pub fn M_GetAll() -> Vec<&'static str> {
    match MYARGV.get() {
        Some(args) => args.iter().map(|s| s.as_str()).collect(),
        None => Vec::new(),
    }
}

/// Returns the number of arguments passed to the program
#[allow(non_snake_case)]
pub fn M_GetArgC() -> i32 {
    *MYARGC.get().unwrap() as i32
}
