use std::fmt;
use std::fs::File;
use std::io;
use std::path::Path;

use serde_derive::Deserialize;

#[derive(Deserialize)]
pub struct MailConfig {
    pub server: String,
    pub login: String,
    pub passwd: String,
    pub from: String,
}

impl fmt::Debug for MailConfig {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("MailConfig")
            .field("server", &self.server)
            .field("login", &self.login)
            .field("from", &self.from)
            .finish()
    }
}

#[derive(Debug, Deserialize)]
pub struct Config {
    pub http: std::net::SocketAddr,
    pub dsn_ro_path: std::path::PathBuf,
    pub dsn_rw_path: std::path::PathBuf,
    pub dsn_conn: usize,
    pub cache_capacity: usize,
    pub cache_duration_sec: u64,
    pub base_proto: String,
    pub base_domain: String,
    pub cookies_key_base64: Option<String>,
    #[serde(default)]
    pub set_cookie_domain: bool,
    pub mail: MailConfig,
    pub xmpp_url: String,
    pub freeorion_version: String,
    #[cfg(feature = "actix-files")]
    pub public: std::path::PathBuf,
}

impl Config {
    pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Self> {
        let mut f = File::open(path)?;
        let mut buffer = String::new();

        use std::io::Read;
        f.read_to_string(&mut buffer)?;
        toml::from_str(&buffer).map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
    }
}

pub fn read_dsn<P: AsRef<Path>>(path: P) -> io::Result<tokio_postgres::config::Config> {
    let mut f = File::open(path)?;
    let mut buffer = String::new();

    use std::io::Read;
    f.read_to_string(&mut buffer)?;

    use std::str::FromStr;
    tokio_postgres::config::Config::from_str(&buffer)
        .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))
}