use serde::{Serialize, Deserialize};

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ServerMeta {
    pub protocol: String,
    pub hostname: String,
    pub port: Option<u16>,
    pub description: String,
    pub name: String, 
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ServerConfig {
    pub user: UserConfig,
    pub server: ServerMeta
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct UserConfig {
    pub id: u64,
    pub secret: String,
    pub jwt: Option<String>,

    pub permissions: u64,
    pub joindate: i64,
    pub status: i32,
}


#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Config {
    pub username: Option<String>,
    pub servers: Vec<ServerConfig>
}


impl Config {
    pub fn update_jwt(&mut self, hostname: String, jwt: String) { 
        for servermeta in self.servers.iter_mut() {
            if servermeta.server.hostname == hostname {
                servermeta.user.jwt = Some(jwt);
                break
            }
        }
    }

    pub fn server_url(&self, hostname: &str) -> Option<String> {
        // Finds the base-url for the given hostname, assuming it exists
        let mut url: Option<String> = None;
        for meta in self.servers.iter() {
            if meta.server.hostname == hostname {
                url = match meta.server.port {
                    Some(p) => Some(format!("{}://{}:{}", meta.server.protocol, hostname, p)),
                    None => Some(format!("{}://{}", meta.server.protocol, hostname))
                };
                break
            }
        }
        return url;
    }

    pub fn save(&self, path: String) -> std::io::Result<()>{
        use std::io::prelude::Write;
        use std::fs::File;

        let content = serde_json::to_string_pretty(self)?;
        let mut file = File::create(path)?;
        file.write(content.as_bytes())?;

        Ok(())
    }
}
