use std::env;

#[derive(Debug, Clone)]
pub struct Config {
    pub port: u16,
    pub region: String,
    pub data_dir: String,
    pub signing_secret: String,
    pub log_level: String,
    pub issuer_base: String,
}

impl Config {
    pub fn from_env() -> Self {
        Self {
            port: env::var("COGNITO_PORT")
                .ok()
                .and_then(|v| v.parse().ok())
                .unwrap_or(9229),
            region: env::var("COGNITO_REGION")
                .unwrap_or_else(|_| "us-east-1".to_string()),
            data_dir: env::var("COGNITO_DATA_DIR")
                .unwrap_or_else(|_| "/data".to_string()),
            signing_secret: env::var("COGNITO_SIGNING_SECRET")
                .unwrap_or_else(|_| "local-cognito-secret".to_string()),
            log_level: env::var("RUST_LOG")
                .or_else(|_| env::var("COGNITO_LOG_LEVEL"))
                .unwrap_or_else(|_| "info".to_string()),
            issuer_base: env::var("COGNITO_ISSUER_BASE").ok().unwrap_or_default(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::sync::Mutex;

    static ENV_LOCK: Mutex<()> = Mutex::new(());

    #[test]
    fn test_defaults() {
        let _lock = ENV_LOCK.lock().unwrap();
        for key in ["COGNITO_PORT", "COGNITO_REGION", "COGNITO_DATA_DIR",
                     "COGNITO_SIGNING_SECRET", "COGNITO_LOG_LEVEL", "RUST_LOG",
                     "COGNITO_ISSUER_BASE"] {
            // SAFETY: test holds ENV_LOCK and runs single-threaded via mutex
            unsafe { env::remove_var(key); }
        }
        let config = Config::from_env();
        assert_eq!(config.port, 9229);
        assert_eq!(config.region, "us-east-1");
        assert_eq!(config.data_dir, "/data");
        assert_eq!(config.signing_secret, "local-cognito-secret");
        assert_eq!(config.log_level, "info");
        assert_eq!(config.issuer_base, "");
    }

    #[test]
    fn test_custom_values() {
        let _lock = ENV_LOCK.lock().unwrap();
        // SAFETY: test holds ENV_LOCK and runs single-threaded via mutex
        unsafe {
            env::set_var("COGNITO_PORT", "8080");
            env::set_var("COGNITO_REGION", "eu-west-1");
        }
        let config = Config::from_env();
        assert_eq!(config.port, 8080);
        assert_eq!(config.region, "eu-west-1");
        // SAFETY: test holds ENV_LOCK and runs single-threaded via mutex
        unsafe {
            env::remove_var("COGNITO_PORT");
            env::remove_var("COGNITO_REGION");
        }
    }

    #[test]
    fn test_rust_log_overrides_cognito_log_level() {
        let _lock = ENV_LOCK.lock().unwrap();
        // SAFETY: test holds ENV_LOCK and runs single-threaded via mutex
        unsafe {
            env::set_var("COGNITO_LOG_LEVEL", "warn");
            env::set_var("RUST_LOG", "debug");
        }
        let config = Config::from_env();
        assert_eq!(config.log_level, "debug");
        // SAFETY: test holds ENV_LOCK and runs single-threaded via mutex
        unsafe {
            env::remove_var("COGNITO_LOG_LEVEL");
            env::remove_var("RUST_LOG");
        }
    }
}
