import json
from typing import (
    List,
    Optional,
)


from ._Group import Group
from ._Key import Key
from ._util import (
    _by_name,
    _by_path,
)


class Configuration(object):
    def __init__(self):
        self.version = "1.0"
        self.groups: List[Group] = []

    def group(self, name: str) -> Optional[Group]:
        return _by_name(self.groups, name)

    def find_group(self, path: str) -> Optional[Group]:
        return _by_path(self, path)

    def find_key(self, path: str) -> Key:
        return _by_path(self, path, is_key=True)

    def find_value(self, path: str, default=None):
        key = _by_path(self, path, is_key=True)
        return default if key is None else key.value()

    def find_values(self, path: str) -> Optional[List[str]]:
        key = _by_path(self, path, is_key=True)
        return None if key is None else key.values

    def add_group(
        self,
        name: str,
        descr: Optional[str] = None,
    ) -> Group:

        grp = Group(name, descr)
        if self.groups:
            self.groups[len(self.groups) - 1].next = grp
        self.groups.append(grp)
        return grp

    def __str__(self):
        return json.dumps(
            {
                "version": self.version,
            }
        )

    def __eq__(self, other):
        if not isinstance(other, Configuration):
            return False

        return self.version == other.version and sorted(self.groups) == sorted(other.groups)

    def write(self, output_io) -> None:
        output_io.write(f'<?xml version="1.0" encoding="UTF-8"?>\n<config version="{self.version}">\n')
        for group in self.groups:
            group.write(output_io, 1)
        output_io.write("</config>\n")
