use std::env; use std::path::PathBuf; const CONFIG_BASE_PATH: &str = "provisioning/platform/config"; /// Resuelve la ruta del archivo de configuración siguiendo la jerarquía: /// 1. Variable de entorno {SERVICE}_CONFIG (ruta explícita) /// 2. Variable de entorno {SERVICE}_MODE + búsqueda de archivo /// 3. Fallback a defaults pub fn resolve_config_path(service_name: &str) -> Option { // Paso 1: Check {SERVICE}_CONFIG env var (explicit path) let env_var = format!("{}_CONFIG", service_name.to_uppercase().replace('-', "_")); if let Ok(path) = env::var(&env_var) { let config_path = PathBuf::from(path); if config_path.exists() { tracing::debug!( "Using explicit config path from {}: {:?}", env_var, config_path ); return Some(config_path); } } // Paso 2: Check {SERVICE}_MODE env var + find config file let mode_var = format!("{}_MODE", service_name.to_uppercase().replace('-', "_")); let mode = env::var(&mode_var).unwrap_or_else(|_| "solo".to_string()); if let Some(path) = find_config_file(service_name, &mode) { tracing::debug!( "Using config file for {}.{}: {:?}", service_name, mode, path ); return Some(path); } // Paso 3: Fallback - no config file found tracing::debug!( "No config file found for {}.{} - using defaults", service_name, mode ); None } /// Busca el archivo de configuración con prioridad: /// 1. {service}.{mode}.ncl /// 2. {service}.{mode}.toml pub fn find_config_file(service_name: &str, mode: &str) -> Option { let base = PathBuf::from(CONFIG_BASE_PATH); // Prioridad 1: .ncl let ncl_path = base.join(format!("{}.{}.ncl", service_name, mode)); if ncl_path.exists() { tracing::trace!("Found NCL config: {:?}", ncl_path); return Some(ncl_path); } // Prioridad 2: .toml let toml_path = base.join(format!("{}.{}.toml", service_name, mode)); if toml_path.exists() { tracing::trace!("Found TOML config: {:?}", toml_path); return Some(toml_path); } None } /// Obtiene la ruta base de configuración (útil para testing) pub fn config_base_path() -> &'static str { CONFIG_BASE_PATH } #[cfg(test)] mod tests { use super::*; #[test] fn test_config_base_path() { assert_eq!(config_base_path(), "provisioning/platform/config"); } #[test] fn test_find_config_file_priority() { // This test demonstrates the priority logic without requiring actual files // In real integration tests, we'd create temporary files let _ = find_config_file("test-service", "solo"); } }