use std::{collections::HashMap, sync::OnceLock};

pub static GLOBAL_CONFIG: OnceLock<AppConfig> = OnceLock::new();

#[derive(Clone, Debug)]
pub struct AppConfig {
    pub env: HashMap<String, String>,
}

impl AppConfig {
    const ENV_FILES: &'static [&'static str] = &[".env", ".env.local"];
    pub fn load() -> AppConfig {
        let mut env = HashMap::new();
        for env_file in AppConfig::ENV_FILES {
            if let Err(e) = dotenvy::from_path(env_file) {
                tracing::debug!(file = %env_file, error = %e, "dotenv load skipped");
            }
            if let Ok(env_file_content) = std::fs::read_to_string(env_file) {
                for line in env_file_content.lines() {
                    if let Some((key, value)) = line.split_once('=') {
                        env.insert(key.to_string(), value.to_string());
                    }
                }
            }
        }
        env = env.into_iter().chain(std::env::vars()).collect();
        let this = AppConfig { env };
        if GLOBAL_CONFIG.get().is_some() {
            GLOBAL_CONFIG.get().unwrap().clone()
        } else {
            let _ = GLOBAL_CONFIG.set(this);
            GLOBAL_CONFIG
                .get()
                .expect("global config should be set after load")
                .clone()
        }
    }
}

pub mod ai;
pub mod app;
pub mod auth;
pub mod avatar;
pub mod cache;
pub mod channel;
pub mod database;
pub mod domain;
pub mod embed;
pub mod git;
pub mod hook;
pub mod logs;
pub mod nats;
pub mod oauth;
pub mod pull_request;
pub mod qdrant;
pub mod redis;
pub mod smtp;
pub mod ssh;
pub mod storage;
