Documentation
/*!
这是工具类所在的包
 */


use std::collections::HashMap;
use std::env;


pub use my_config::{MyCommand, MyConfig};
pub use help_info::{print_help_info};


mod my_config;
mod help_info;

/**
 将 [`Vec<String>`] 解析成 [`HashMap<String, String>`]

 # 示例
 ```
use wantora::resolve_args;
use std::collections::HashMap;

let r: Vec<String> = vec![
    "--name".to_string(),
    "aaa".to_string(),
    "--skipGit".to_string(),
];
let args: HashMap<String, String> = resolve_args(r);
 ```
 */
pub fn resolve_args(cmd_args: Vec<String>) -> HashMap<String, String> {
    let mut r = HashMap::new();
    let mut iter = cmd_args.iter().peekable();
    while let Some(item) = iter.next() {
        if !item.starts_with("--") { continue; }
        let key = item.trim_start_matches("--").to_string();
        if let Some(next_item) = iter.peek() {
            if next_item.starts_with("--") {
                r.insert(key, "true".to_string());
            } else {
                r.insert(key, next_item.to_string());
                iter.next();//跳过下一个元素
            }
        } else {
            r.insert(key, "true".to_string());
        }
    }
    r
}

pub fn get_config() -> Result<MyConfig, String> {
    let args: Vec<String> = env::args().skip(1).collect();
    resolve_config(args)
}

fn resolve_config(args: Vec<String>) -> Result<MyConfig, String> {
    if args.len() < 2 {
        return Ok(MyConfig { command: MyCommand::HELP, name: None, title: None, skip_git: false });
    }
    match args.get(0).map(|s| s.as_str()) {
        Some("init") => {
            let map = resolve_args(args);
            if let None = map.get("name") {
                return Err("没有找到name参数,请确认是否使用了--name传入参数".to_string());
            }
            let name = map.get("name").unwrap().to_string();
            let title = map.get("title").unwrap_or(&name).to_string();
            let skip_git = map.get("skipGit").map(|_| { true }).unwrap_or(false);
            return Ok(MyConfig { command: MyCommand::INIT, name: Some(name), title: Some(title), skip_git });
        }
        Some("run") => { Ok(MyConfig { command: MyCommand::RUN, name: None, title: None, skip_git: false }) }
        Some("build") => { Ok(MyConfig { command: MyCommand::BUILD, name: None, title: None, skip_git: false }) }
        _ => { Ok(MyConfig { command: MyCommand::HELP, name: None, title: None, skip_git: false }) }
    }
}

#[cfg(test)]
mod test {
    use super::*;

    /**
    测试正确读取参数
     */
    #[test]
    fn can_get_correct_cmd_args() {
        let r: Vec<String> = vec![
            "init".to_string(),
            "--name".to_string(),
            "aaa".to_string(),
            "--skipGit".to_string(),
        ];
        let args = resolve_args(r);
        assert_eq!("aaa", args.get("name").unwrap());
        assert_eq!("true", args.get("skipGit").unwrap());
        assert_eq!(None, args.get("skipInit"));
    }

    #[test]
    fn get_config_test() {
        let args: Vec<String> = "wantora init".split(" ").map(|s| s.to_string()).skip(1).collect();
        let config = resolve_config(args).unwrap();
        assert_eq!(config.command, MyCommand::HELP);

        let args: Vec<String> = "wantora init --name demo1 --skipGit".split(" ").map(|s| s.to_string()).skip(1).collect();
        let config = resolve_config(args).unwrap();
        assert_eq!(config.command, MyCommand::INIT);
        assert_eq!(config.name, Some("demo1".to_string()));

        let args: Vec<String> = "wantora init --name demo1 --skipGit --title 测试title".split(" ").map(|s| s.to_string()).skip(1).collect();
        let config = resolve_config(args).unwrap();
        assert_eq!(config.command, MyCommand::INIT);
        assert_eq!(config.name, Some("demo1".to_string()));
        assert_eq!(config.title, Some("测试title".to_string()));
    }

    #[test]
    fn get_config_without_name() {
        let args: Vec<String> = "wantora init --skipGit".split(" ").map(|s| s.to_string()).skip(1).collect();
        if let Err(e) = resolve_config(args) {
            assert_eq!(e, "没有找到name参数,请确认是否使用了--name传入参数");
        }
    }
}