"""Source for INI configuration files via configparser."""
from __future__ import annotations

from configparser import ConfigParser, SectionProxy
from pathlib import Path
from typing import Dict

from pytoolconfig.sources.source import Source
from pytoolconfig.types import Key
from pytoolconfig.utils import find_config_file


def _add_split_to_dict(
    dest: dict[str, Key],
    table_to_add: list[str],
    table: SectionProxy,
) -> None:
    if len(table_to_add) == 0:
        for table_key in table:
            dest[table_key] = table[table_key]
    else:
        first = table_to_add[0]
        dest.setdefault(first, {})
        assert isinstance(dest[first], Dict)
        _add_split_to_dict(dest[first], table_to_add[1:], table)


class IniConfig(Source):

    """Source for INI configuration files via configparser."""

    _config: ConfigParser
    name: str
    description: str | None

    def __init__(
        self,
        working_directory: Path,
        filename: str,
        base_table: str,
        description: str | None = None,
    ) -> None:
        """Initialize the Ini Configuration.

        :param working_directory: the working directory to search.
        :param filename: the filename to search for.
        :param base_table: The table to search for.
            The file will only be used if this is present.
            The base_table will not be included in the parsed output.
        :param description: The description used in documentation.
        """
        self.file = find_config_file(working_directory, filename)
        self.base_table = base_table
        self.name = filename
        self.description = description
        self._config = ConfigParser()

    def _read(self) -> bool:
        if self.file is None:
            return False
        self._config.read_string(self.file.read_text())
        for table in self._config:
            split = table.split(".")
            if split[0] == self.base_table:
                return True
        return False

    def parse(self) -> dict[str, Key] | None:
        """Parse the INI file."""
        if not self._read():
            return None
        output: dict[str, Key] = {}
        for table in self._config:
            split = table.split(".")
            if split[0] == self.base_table:
                _add_split_to_dict(output, split[1:], self._config[table])
        return output
