import os
from typing import Any

import yaml

from logger import Logger
from tool import Singleton, Tool


class Config(metaclass=Singleton):  # type: ignore[metaclass]
    """
    Configuration manager wrapping PyYaml.

    This class handles the loading of YAML configuration files from a specific directory.
    It implements the Singleton pattern to ensure centralized configuration management.
    """

    __slots__ = ["_me", "_logger", "_tool", "_skills_file", "data"]

    def __init__(self) -> None:
        self._me = self.__class__.__name__
        self._logger = Logger(caller_class=self._me)
        self._logger.set_logger(caller_class=self._me)
        self._tool = Tool()
        self.data: dict[str, Any] = {}

    def get_data(self, needed_file: str = "", _config_dir: str = "config", create_if_not_exist: bool = False) -> None:
        """
        Load configuration files from the config directory.

        It scans the directory for YAML files and loads them into `self.data`.

        Args:
            needed_file (str, optional): A specific file to load. If empty, loads all YAML files in the directory.
                                         Defaults to "".
            _config_dir (str, optional): Name of the configuration directory. Defaults to "config".
            create_if_not_exist (bool, optional): Create the config directory if it doesn't exist. Defaults to False.
        """
        config_dir = self._tool.get_dir(_config_dir)

        if (not config_dir or not os.path.exists(config_dir)) and create_if_not_exist:
            os.makedirs(_config_dir, exist_ok=True)
            config_dir = self._tool.formatted_from_os(os.path.abspath(_config_dir))

        if needed_file:
            filename = os.path.basename(needed_file).split(".")[0]
            with open(f"{config_dir}{needed_file}", encoding="utf8") as nf:
                self._logger.add(level="info", caller=self._me, message=f"Load '{filename}' file ...")
                self.data[filename] = yaml.safe_load(nf)
        else:
            for file in os.listdir(config_dir):
                try:
                    (filename, ext) = os.path.basename(file).split(".")
                except ValueError:
                    continue
                if ext in ["yml", "yaml"] and filename not in self.data.keys():
                    with open(f"{config_dir}{file}", encoding="utf8") as f:
                        self._logger.add(level="info", caller=self._me, message=f"Load '{filename}' file ...")
                        self.data[filename] = yaml.safe_load(f)
