import 'package:flutter_dotenv/flutter_dotenv.dart'; import '../core/exceptions/invalid_environment_exception.dart'; import 'app_config.dart'; import '../data/firebase/models/firebase_config.dart'; /// Loads application configuration based on the specified environment. /// /// This class provides a factory method to load configuration for either /// 'dev' or 'prod' environments. It throws [InvalidEnvironmentException] /// if an invalid environment is provided. class ConfigLoader { /// Private constructor to prevent instantiation. ConfigLoader._(); /// Loads configuration for the specified environment. /// /// Reads from .env file if available, falls back to hardcoded defaults. /// /// [environment] - The environment to load ('dev' or 'prod'). /// /// Returns an [AppConfig] instance for the specified environment. /// /// Throws [InvalidEnvironmentException] if [environment] is not 'dev' or 'prod'. static AppConfig load(String environment) { final env = environment.toLowerCase(); // Helper to get env var or fallback to default // Handles case where dotenv is not initialized (e.g., in tests) String getEnv(String key, String defaultValue) { try { return dotenv.env[key] ?? defaultValue; } catch (e) { // dotenv not initialized, use default return defaultValue; } } // Helper to parse boolean from env bool getBoolEnv(String key, bool defaultValue) { try { final value = dotenv.env[key]; if (value == null) return defaultValue; return value.toLowerCase() == 'true'; } catch (e) { // dotenv not initialized, use default return defaultValue; } } // Helper to parse comma-separated list from env List getListEnv(String key, List defaultValue) { try { final value = dotenv.env[key]; if (value == null || value.isEmpty) return defaultValue; return value.split(',').map((s) => s.trim()).where((s) => s.isNotEmpty).toList(); } catch (e) { // dotenv not initialized, use default return defaultValue; } } // Helper to create FirebaseConfig from environment variables FirebaseConfig createFirebaseConfig() { return FirebaseConfig( enabled: getBoolEnv('FIREBASE_ENABLED', false), firestoreEnabled: getBoolEnv('FIREBASE_FIRESTORE_ENABLED', true), storageEnabled: getBoolEnv('FIREBASE_STORAGE_ENABLED', true), authEnabled: getBoolEnv('FIREBASE_AUTH_ENABLED', true), messagingEnabled: getBoolEnv('FIREBASE_MESSAGING_ENABLED', true), analyticsEnabled: getBoolEnv('FIREBASE_ANALYTICS_ENABLED', true), ); } switch (env) { case 'dev': return AppConfig( apiBaseUrl: getEnv('API_BASE_URL_DEV', 'https://api-dev.example.com'), enableLogging: getBoolEnv('ENABLE_LOGGING_DEV', true), immichBaseUrl: getEnv('IMMICH_BASE_URL', 'https://photos.satoshinakamoto.win'), immichApiKey: getEnv('IMMICH_API_KEY_DEV', 'your-dev-api-key-here'), immichEnabled: getBoolEnv('IMMICH_ENABLE', true), blossomServer: getEnv('BLOSSOM_SERVER', 'https://media.based21.com'), nostrRelays: getListEnv('NOSTR_RELAYS_DEV', [ 'wss://nostrum.satoshinakamoto.win', 'wss://nos.lol', ]), firebaseConfig: createFirebaseConfig(), ); case 'prod': return AppConfig( apiBaseUrl: getEnv('API_BASE_URL_PROD', 'https://api.example.com'), enableLogging: getBoolEnv('ENABLE_LOGGING_PROD', false), immichBaseUrl: getEnv('IMMICH_BASE_URL', 'https://photos.satoshinakamoto.win'), immichApiKey: getEnv('IMMICH_API_KEY_PROD', 'your-prod-api-key-here'), immichEnabled: getBoolEnv('IMMICH_ENABLE', true), blossomServer: getEnv('BLOSSOM_SERVER', 'https://media.based21.com'), nostrRelays: getListEnv('NOSTR_RELAYS_PROD', [ 'wss://relay.damus.io', ]), firebaseConfig: createFirebaseConfig(), ); default: throw InvalidEnvironmentException(environment); } } }