use rocket::figment::Figment;
use rocket::serde::Deserialize;
use std::path::PathBuf;

pub const DEFAULT_MAIL_RATE_LIMIT: u64 = 60; // in seconds
pub const DEFAULT_MAINTENANCE_FILE_NAME: &str = "maintenance";
pub const DEFAULT_LOCALIZED_TEMPLATE_DIR_NAME: &str = "localized";

pub fn load(figment: &Figment) -> Configuration {
    figment
        .extract::<Configuration>()
        .expect("Rocket config must succeed")
}

#[derive(Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct Configuration {
    // database
    pub keys_internal_dir: PathBuf,
    // hagrid state
    pub assets_dir: PathBuf,
    // state
    #[serde(rename = "base-URI")]
    pub base_uri: String,
    #[serde(rename = "base-URI-Onion")]
    pub base_uri_onion: Option<String>,
    // stateful_token_service
    pub token_dir: PathBuf,
    // stateless_token_service
    pub token_secret: String,
    pub token_validity: u64,
    // mail_service
    pub email_template_dir: PathBuf,
    pub from: String,
    pub filemail_into: Option<PathBuf>,
    pub local_smtp: Option<bool>,
    // rate_limiter
    #[serde(default = "Configuration::default_mail_rate_limit")]
    pub mail_rate_limit: u64,
    // maintenance
    #[serde(default = "Configuration::default_maintenance_file")]
    pub maintenance_file: PathBuf,
    // localized_template_list
    pub template_dir: PathBuf,
    // prometheus
    #[serde(default)]
    pub enable_prometheus: bool,
}

impl Configuration {
    pub fn base_uri_onion(&self) -> &str {
        self.base_uri_onion
            .as_deref()
            .unwrap_or_else(|| &self.base_uri)
    }

    pub fn default_mail_rate_limit() -> u64 {
        DEFAULT_MAIL_RATE_LIMIT
    }

    pub fn default_maintenance_file() -> PathBuf {
        PathBuf::from(DEFAULT_MAINTENANCE_FILE_NAME)
    }
}
