""" Configuration Manager for the application. Handles loading and saving of application settings to a JSON file. """ import json from pathlib import Path from typing import Dict, Any, Optional, List from . import logger from ..core.export_profiles import ExportProfile, ExportField log = logger.get_logger(__name__) class ConfigManager: """Manages loading and saving configuration from/to a JSON file.""" def __init__(self, config_path: Path): self.config_path: Path = config_path self.config: Dict[str, Any] = self._get_default_config() self.export_profiles: List[ExportProfile] = [] @staticmethod def _get_default_config() -> Dict[str, Any]: """Provides the default configuration structure.""" # Updated default profile with correct data paths for the new architecture default_profile = ExportProfile( name="Default", fields=[ ExportField(column_name="batch_id", data_path="batch_id"), ExportField(column_name="timetag", data_path="main_header.timetag"), ExportField( column_name="file_batch_counter", data_path="main_header.batch_counter", ), ExportField(column_name="npri", data_path="main_header.npri"), ExportField(column_name="nrbin", data_path="main_header.nrbin"), ], ) return { "last_opened_file": "", "last_output_file": "", "active_export_profile_name": "Default", "export_profiles": [default_profile.to_dict()], } def load_config(self) -> None: """Loads the configuration from the JSON file.""" log.info(f"Attempting to load configuration from: {self.config_path}") if self.config_path.is_file(): try: with open(self.config_path, "r", encoding="utf-8") as f: loaded_data = json.load(f) self.config["last_opened_file"] = loaded_data.get( "last_opened_file", "" ) self.config["last_output_file"] = loaded_data.get( "last_output_file", "" ) self.config["active_export_profile_name"] = loaded_data.get( "active_export_profile_name", "Default" ) profiles_data = loaded_data.get("export_profiles", []) self.export_profiles = [ ExportProfile.from_dict(p_data) for p_data in profiles_data ] if not self.export_profiles: log.warning("No export profiles found in config, loading defaults.") self._load_default_profiles() log.info( f"Configuration loaded successfully. Found {len(self.export_profiles)} export profiles." ) except (json.JSONDecodeError, IOError, KeyError) as e: log.error(f"Failed to load or parse config file: {e}. Using defaults.") self._load_defaults() else: log.warning("Configuration file not found. Using default settings.") self._load_defaults() def _load_defaults(self): """Loads all default settings into the manager.""" self.config = self._get_default_config() self._load_default_profiles() def _load_default_profiles(self): """Loads just the default profiles from the default config.""" default_conf = self._get_default_config() profiles_data = default_conf.get("export_profiles", []) self.export_profiles = [ ExportProfile.from_dict(p_data) for p_data in profiles_data ] def save_config(self) -> None: """Saves the current configuration to the JSON file.""" log.info(f"Saving configuration to: {self.config_path}") data_to_save = { "last_opened_file": self.get("last_opened_file", ""), "last_output_file": self.get("last_output_file", ""), "active_export_profile_name": self.get( "active_export_profile_name", "Default" ), "export_profiles": [profile.to_dict() for profile in self.export_profiles], } try: self.config_path.parent.mkdir(parents=True, exist_ok=True) with open(self.config_path, "w", encoding="utf-8") as f: json.dump(data_to_save, f, indent=4) log.info("Configuration saved successfully.") except IOError as e: log.error(f"Failed to save configuration file: {e}") def get(self, key: str, default: Optional[Any] = None) -> Any: """Gets a value from the configuration.""" return self.config.get(key, default) def set(self, key: str, value: Any) -> None: """Sets a value in the configuration.""" self.config[key] = value def get_export_profiles(self) -> List[ExportProfile]: """Returns the list of loaded export profiles.""" return self.export_profiles def save_export_profiles(self, profiles: List[ExportProfile]): """Updates the list of export profiles and saves the config.""" self.export_profiles = profiles self.save_config()