Documentation
/*!
这是配置相关逻辑所在的包
 */

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

mod help_info;

pub use help_info::print_help_info;

/// 主配置struct
#[derive(Debug)]
pub struct MyConfig {
    /// 命令
    pub command: MyCommand,
    /// 名称,初始化命令使用的参数,必填
    pub name: Option<String>,
    /// 标题,初始化命令使用的参数,如果不填则默认取name的值
    pub title: Option<String>,
    /// 是否跳过git,初始化命令使用的参数,默认为false。默认情况下会执行git命令,生成.git目录。如果设置成true则表示不执行git命令,不生成.git目录
    pub skip_git: bool,
}

/// 命令枚举
#[derive(Debug)]
#[derive(PartialEq)]
pub enum MyCommand {
    ///初始化
    INIT,
    ///执行antora本地开发服务器,随时监控文件变化并编译
    RUN,
    ///打包antora项目
    BUILD,
    ///帮助
    HELP,
}


/// 解析参数
///
/// 将 [`Vec<String>`] 解析成 [`HashMap<String, String>`]
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)
}

///解析配置,根据命令行参数,解析成配置struct返回
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()));
    }

    ///测试没传入name时的报错信息
    #[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传入参数");
        }
    }
}