use crate::string::StringExentd;
use crate::JsonV;

/// 优先级: 从启动参数里获取参数 key=value ＞ 从缓存的配置文件读取的数据(toml文件读取) > 从环境变量中获取 key=value
/// let t_arg = get_arg("t").parse().unwrap_or(3);
pub fn get_arg(input_k: impl AsRef<str>) -> JsonV {
    let input_k = input_k.as_ref();

    if let Some(v) = get_os_args(&input_k) {
        return JsonV::String(v);
    }

    // 优先读取监听的文件里面的值
    // 再去读取mode中定义的配置文件路径
    if let Some(mode) = get_arg_2("_watch_mode").as_str() {
        let modes = mode.split_char(",");
        for mode in modes {
            let mode = mode.trim();
            if mode == "" {
                continue;
            }
            let r = get_arg_2(&format!("{}.{}", mode, input_k));
            if !r.is_null() {
                return r;
            }
        }
    }

    // 如果有mode参数, 将获得模式前缀数据,
    // mode = "prod"
    // mode = "mvc_config,prod" # 可以定义多个配置文件,按顺序读取
    //
    // 比如之前是
    // [api]
    // key = "xxx"
    //
    // 现在是优先获取以下数据, 获取不到再取以上数据:
    // [prod.api]
    // key = "yyyy"
    //
    if let Some(mode) = get_arg_2("mode").as_str() {
        let modes = mode.split_char(",");
        for mode in modes {
            let mode = mode.trim();
            if mode == "" {
                continue;
            }
            let r = get_arg_2(&format!("{}.{}", mode, input_k));
            if !r.is_null() {
                return r;
            }
        }
    }

    let r = get_arg_2(input_k);
    if let JsonV::Null = r {
        let default_name = match get_arg_2("_default_name") {
            JsonV::String(v) => v,
            _ => "default".to_owned(),
        };
        return get_arg_2(&format!("{}.{}", default_name, input_k));
    } else {
        r
    }
}

fn get_arg_2(input_k: &str) -> JsonV {
    // 读取命令行上面的参数
    if let Some(v) = get_os_args(&input_k) {
        return JsonV::String(v);
    }

    // 读取缓存数据
    #[cfg(feature = "use_toml")]
    match get_cache_args(input_k) {
        JsonV::Null => (),
        v => return v,
    }

    // 读取环境数据
    match get_env_args(input_k) {
        None => JsonV::Null,
        Some(v) => JsonV::String(v),
    }
}

/// 读取命令行上面的参数,例如: ./xxx.exe -config=value
/// 输入参数 -config,读取到 value
fn get_os_args(input_k: &str) -> Option<String> {
    // println!("std::env::args_os(): {:?}", std::env::args_os());
    let k = &format!("{}=", input_k);
    let r = std::env::args_os()
        .find(|v| v.to_str().unwrap_or_default().starts_with(k))
        .map(|v| v.to_str().unwrap_or_default().trim_start_matches(k).to_string());
    trace!("get_os_args({}) -> {:?}", input_k, &r);
    r
}

/// 读取缓存数据
#[cfg(feature = "use_toml")]
fn get_cache_args(input_k: &str) -> JsonV {
    let keys = input_k.split(".").collect::<Vec<&str>>();
    let rr = crate::toml_read::get_config(keys);
    if !rr.is_null() {
        trace!("get_cache_args({}) -> {:?}", input_k, &rr);
    }
    rr
}

/// 读取环境数据
fn get_env_args(k: &str) -> Option<String> {
    use std::ffi::OsString;
    let option = std::env::var_os(k);
    let string = option.unwrap_or(OsString::from(""));
    let s = string.to_str().unwrap_or("").to_string();
    let r = if s == "" { None } else { Some(s) };

    trace!("get_env_args({}) -> {:?}", k, &r);
    r
}

#[test]
fn test_get_arg() {
    // let arg = get_arg("log");
    // println!("{:?}", arg);

    let arg = get_arg("api.port".to_string());
    println!("get_arg: {:?}", arg);
}
