"""Treestamps Config methods."""

from collections.abc import Iterable, Mapping
from dataclasses import dataclass
from types import MappingProxyType


@dataclass
class CommonConfig:
    """Common Config meant to be subclassed."""

    program_name: str
    verbose: int = 0
    symlinks: bool = True
    ignore: Iterable[str] = frozenset()
    check_config: bool = True
    program_config: Mapping | None = None
    program_config_keys: Iterable[str] = frozenset()

    @classmethod
    def _normalize_config(cls, config: Mapping | None) -> MappingProxyType | None:
        """Recursively convert iterables into sorted unique lists."""
        if config is None:
            return None
        new_config: dict = {}
        for key, value in config.items():
            if isinstance(value, list | tuple | set | frozenset):
                new_config[key] = tuple(sorted(frozenset(value)))
            elif isinstance(value, Mapping):
                normalized = cls._normalize_config(value)
                if normalized is not None:
                    normalized = MappingProxyType(dict(sorted(normalized.items())))
                new_config[key] = normalized
            else:
                new_config[key] = value

        return MappingProxyType(new_config)

    def __post_init__(self):
        """Fix types and normalize program config dict."""
        self.ignore = frozenset(self.ignore)
        self.program_config_keys = frozenset(self.program_config_keys)

        # Filter dict by keys
        if self.program_config:

            def filter_func(pair):
                return pair[0] in self.program_config_keys

            self.program_config = dict(filter(filter_func, self.program_config.items()))

        self.program_config = self._normalize_config(self.program_config)
