use json::{JsonValue};

#[derive(Clone, Debug)]
pub struct Config {
    /// 开启调试
    pub debug: bool,
    /// 服务器 主机 host
    pub host: String,
    /// 服务器 端口 port
    pub port: String,
    /// 域名
    pub domain: String,
    /// 服务器地址
    pub url: String,
    /// 对外访问目录
    pub public: String,
    /// 运行目录
    pub runtime: String,
    /// 安全协议
    pub ssl: bool,
    /// 私钥文件
    pub ssl_pkey: String,
    /// 公钥文件
    pub ssl_certs: String,
    /// 跨域请求配置
    pub cors: Cors,
}

impl Config {
    /// 默认
    pub fn default() -> Self {
        Self {
            domain: "".to_string(),
            url: "".to_string(),
            host: "0.0.0.0".to_string(),
            port: "3535".to_string(),
            public: "public".to_string(),
            runtime: "runtime".to_string(),
            cors: Cors::default(),
            ssl: false,
            ssl_pkey: "".to_string(),
            ssl_certs: "".to_string(),
            debug: false,
        }
    }
    /// 加载数据
    pub fn from(data: JsonValue) -> Self {
        Self {
            host: data["host"].to_string(),
            port: data["port"].to_string(),
            domain: data["domain"].to_string(),
            url: "".to_string(),
            public: data["public"].to_string(),
            runtime: data["runtime"].to_string(),
            cors: Cors::from(data["cors"].clone()),
            ssl: data["ssl"].as_bool().unwrap_or(false),
            ssl_pkey: data["ssl_pkey"].to_string(),
            ssl_certs: data["ssl_certs"].to_string(),
            debug: data["debug"].as_bool().unwrap_or(false),
        }
    }
    pub fn json(self) -> JsonValue {
        let res = format!("{:?}", self);
        let res = res.replace("Config {", "{");
        let res = res.replace("Cors", "");
        let res = res.replace(",},", "}");
        let res = res.replace(": ", "\": ");
        let res = res.replace("{ ", "{ \"");
        let res = res.replace(", ", ", \"");
        json::parse(&*res).unwrap()
    }
}


/// 跨域资源共享
#[derive(Clone, Debug)]
pub struct Cors {
    /// 源
    pub allow_origin: Vec<String>,
    /// 请求中可以使用那些请求方法
    pub allow_methods: String,
    /// 请求中可以使用那些
    pub(crate) allow_headers: String,
    /// 响应暴露给前端 JavaScript
    pub allow_credentials: bool,
    /// 跨域请求请求头中允许携带的除Cache-Controller、Content-Language、Content-Type、Expires、Last-Modified、Pragma这六个基本字段之外的其他字段信息
    pub expose_headers: String,
    /// 准备响应前的缓存持续的最大时间（以秒为单位,目的是减少浏览器预检请求/响应交互的数量。默认值1800s。设置了该值后，浏览器将在设置值的时间段内对该跨域请求不再发起预请求
    pub max_age: i32,
}

impl Cors {
    /// 默认
    pub fn default() -> Self {
        Self {
            allow_origin: vec![],
            allow_methods: "GET,POST".to_string(),
            allow_headers: "content-type,X-Requested-With,x-api,x-token,x-mode".to_string(),
            allow_credentials: true,
            expose_headers: "content-disposition".to_string(),
            max_age: 1800,
        }
    }
    /// 转JSONValue
    pub fn json(self) -> JsonValue {
        let res = format!("{:?}", self);
        let res = res.replace("Cors {", "{");
        let res = res.replace(",},", "}");
        let res = res.replace(": ", "\": ");
        let res = res.replace("{ ", "{ \"");
        let res = res.replace(", ", ", \"");
        json::parse(&*res).unwrap()
    }
    pub fn from(data: JsonValue) -> Self {
        Self {
            allow_origin: data["allow_origin"].members().map(|x| x.to_string()).collect(),
            allow_methods: data["allow_methods"].to_string(),
            allow_headers: data["allow_headers"].to_string(),
            allow_credentials: data["allow_credentials"].as_bool().unwrap_or(true),
            expose_headers: data["expose_headers"].to_string(),
            max_age: data["max_age"].as_i32().unwrap_or(1800),
        }
    }
}
