use std::fs;
use json::{JsonValue, object};


/// 框架配置
#[derive(Clone, Debug)]
pub struct Config {
    /// 启用日志
    pub log: bool,
    /// 启动扩展列表
    pub extend: Vec<String>,
    /// 隐藏插件列表
    pub addon_hide: Vec<String>,
    /// 开启wss请求
    pub wss: bool,
    /// 开启http请求
    pub web: bool,
    /// 缓存启动
    pub cache: bool,
    /// 密钥失效时间
    pub token_exp: u64,
    /// 服务器令牌
    pub token: String,
    /// 证书路径
    pub pub_key_path: String,
    /// 分析系统
    pub analysis: Vec<String>,
    /// APP可用插件
    pub app_addon: Vec<String>,
    /// 运行目录
    pub root_path: String,
}

impl Config {
    pub fn load(path: &str) -> Self {
        let json = match fs::read_to_string(path) {
            Ok(e) => json::parse(&*e).unwrap(),
            Err(_) => {
                let json = object! {
                    "default":"base",
                    "connections":object! {
                        "base": {
                            "log": true,
                            "extend": [],
                            "addon_hide": [],
                            "wss":false,
                            "web":false,
                            "cache":false,
                            "token_exp":60*60*4,
                            "token":"",
                            "pub_key_path":"",
                            "analysis":[],
                            "app_addon":[],
                            "root_path":""
                        }
                    }
                };
                fs::write(path, json.to_string()).unwrap();
                json
            }
        };
        Config::from(json)
    }
    pub fn from(data: JsonValue) -> Self {
        let default = data["default"].as_str().unwrap();
        let connection = data["connections"][default].clone();
        let addon_hide = connection["addon_hide"].members().map(|x| x.to_string()).collect::<Vec<String>>().clone();
        Config {
            log: connection["log"].as_bool().unwrap_or(true),
            extend: connection["extend"].members().map(|x| x.to_string()).collect::<Vec<String>>().clone(),
            addon_hide,
            wss: connection["wss"].as_bool().unwrap_or(false),
            web: connection["web"].as_bool().unwrap_or(false),
            cache: connection["cache"].as_bool().unwrap_or(false),
            token_exp: connection["token_exp"].as_u64().unwrap_or(60 * 60 * 4),
            token: connection["token"].to_string(),
            pub_key_path: connection["pub_key_path"].to_string(),
            analysis: connection["analysis"].members().map(|x| x.to_string()).collect::<Vec<String>>().clone(),
            app_addon: connection["app_addon"].members().map(|x| x.to_string()).collect::<Vec<String>>().clone(),
            root_path: connection["root_path"].as_str().unwrap_or("").to_string(),
        }
    }
    pub fn default() -> Self {
        Config {
            log: false,
            extend: vec![],
            addon_hide: vec![],
            wss: false,
            web: false,
            cache: false,
            token_exp: 60 * 10,
            token: "".to_string(),
            pub_key_path: "".to_string(),
            analysis: vec![],
            app_addon: vec![],
            root_path: "".to_string(),
        }
    }
}