Documentation
use std::collections::BTreeMap;
use std::fs;
use std::path::PathBuf;
use log::info;
use serde::{Deserialize, Serialize};
use crate::Connection;

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Config {
    pub default: String,
    pub connections: BTreeMap<String, Connection>,
}

impl Default for Config {
    fn default() -> Self {
        let mut connections = BTreeMap::new();
        connections.insert("my_name".to_string(), Connection::default());
        Self {
            default: "my_name".to_string(),
            connections,
        }
    }
}

impl Config {
    /// 创建配置
    /// * config_file 配置文件地址
    /// * path 是否显示包名
    pub fn create(config_file: PathBuf, pkg_name: bool) -> Config {
        #[derive(Clone, Debug, Deserialize, Serialize)]
        pub struct ConfigNew {
            pub br_oss: Config,
        }
        impl ConfigNew {
            pub fn default() -> ConfigNew {
                let mut connections = BTreeMap::new();
                connections.insert("my_name".to_string(), Connection::default());
                Self {
                    br_oss: Config {
                        default: "my_name".to_string(),
                        connections,
                    },
                }
            }
        }
        match fs::read_to_string(config_file.clone()) {
            Ok(e) => {
                if pkg_name {
                    let data = ConfigNew::default();
                    toml::from_str::<ConfigNew>(&e).unwrap_or_else(|err| {
                        if err.span().unwrap().start == 0 && err.span().unwrap().end == 0 {
                            let toml_str = toml::to_string_pretty(&data).unwrap();
                            let _ = fs::write(config_file.clone(), e + "\r\n\r\n" + &*toml_str);
                        } else {
                            let field = err.message().trim_start_matches("missing field `").trim_end_matches("`");
                            let channel=data.br_oss.connections.get(&data.br_oss.default).unwrap().channel.clone();
                            let res = match field {
                                "default" => format!("\r\n{field} = {}", data.br_oss.default),
                                "access_key_id" => format!("\r\n{field} = {:?}", data.br_oss.connections.get(&data.br_oss.default).unwrap().access_key_id),
                                "access_key_secret" => format!("\r\n{field} = {:?}", data.br_oss.connections.get(&data.br_oss.default).unwrap().access_key_secret),
                                "bucket_name" => format!("\r\n{field} = {:?}", data.br_oss.connections.get(&data.br_oss.default).unwrap().bucket_name),
                                "endpoint" => format!("\r\n{field} = {:?}", data.br_oss.connections.get(&data.br_oss.default).unwrap().endpoint),
                                "channel" => format!("\r\n{field} = \"{channel:?}\""),
                                _ => {
                                    info!("配置文件需添加参数: {field}");
                                    "".to_string()
                                }
                            };
                            let text = format!("{}{}{}", &e[..err.span().unwrap().end], res, &e[err.span().unwrap().end..]);
                            let _ = fs::write(config_file.clone(), text);
                        }
                        data
                    }).br_oss
                } else {
                    let data = Config::default();
                    toml::from_str::<Config>(&e).unwrap_or_else(|_| {
                        let toml_str = toml::to_string_pretty(&data).unwrap();
                        let _ = fs::write(config_file.clone(), e + "\r\n\r\n" + &*toml_str);
                        data
                    })
                }
            }
            Err(_) => {
                if pkg_name {
                    let data = ConfigNew::default();
                    fs::create_dir_all(config_file.parent().unwrap()).unwrap();
                    let toml = toml::to_string_pretty(&data).unwrap();
                    let _ = fs::write(config_file.to_str().unwrap(), toml);
                    data.br_oss
                } else {
                    let data = Config::default();
                    fs::create_dir_all(config_file.parent().unwrap()).unwrap();
                    let toml = toml::to_string_pretty(&data).unwrap();
                    let _ = fs::write(config_file.to_str().unwrap(), toml);
                    data
                }
            }
        }
    }
}