use rand::{
    distributions::{Alphanumeric, DistString},
    Rng,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_with::serde_as;
use url::Url;
use super::ConfigurationSection;
fn default_homeserver() -> String {
    "localhost:8008".to_owned()
}
fn default_endpoint() -> Url {
    Url::parse("http://localhost:8008/").unwrap()
}
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MatrixConfig {
    #[serde(default = "default_homeserver")]
    pub homeserver: String,
    pub secret: String,
    #[serde(default = "default_endpoint")]
    pub endpoint: Url,
}
impl ConfigurationSection for MatrixConfig {
    const PATH: Option<&'static str> = Some("matrix");
}
impl MatrixConfig {
    pub(crate) fn generate<R>(mut rng: R) -> Self
    where
        R: Rng + Send,
    {
        Self {
            homeserver: default_homeserver(),
            secret: Alphanumeric.sample_string(&mut rng, 32),
            endpoint: default_endpoint(),
        }
    }
    pub(crate) fn test() -> Self {
        Self {
            homeserver: default_homeserver(),
            secret: "test".to_owned(),
            endpoint: default_endpoint(),
        }
    }
}
#[cfg(test)]
mod tests {
    use figment::{
        providers::{Format, Yaml},
        Figment, Jail,
    };
    use super::*;
    #[test]
    fn load_config() {
        Jail::expect_with(|jail| {
            jail.create_file(
                "config.yaml",
                r"
                    matrix:
                      homeserver: matrix.org
                      secret: test
                ",
            )?;
            let config = Figment::new()
                .merge(Yaml::file("config.yaml"))
                .extract_inner::<MatrixConfig>("matrix")?;
            assert_eq!(&config.homeserver, "matrix.org");
            assert_eq!(&config.secret, "test");
            Ok(())
        });
    }
}