from benedict.dicts import KeylistDict
from benedict.dicts.keypath import keypath_util


class KeypathDict(KeylistDict):
    _keypath_separator = None

    def __init__(self, *args, **kwargs):
        self._keypath_separator = kwargs.pop("keypath_separator", ".")
        check_keys = kwargs.pop("check_keys", True)
        super().__init__(*args, **kwargs)
        if check_keys:
            keypath_util.check_keys(self, self._keypath_separator)

    @property
    def keypath_separator(self):
        return self._keypath_separator

    @keypath_separator.setter
    def keypath_separator(self, value):
        keypath_util.check_keys(self, value)
        self._keypath_separator = value

    def __contains__(self, key):
        return super().__contains__(self._parse_key(key))

    def __delitem__(self, key):
        super().__delitem__(self._parse_key(key))

    def __getitem__(self, key):
        return super().__getitem__(self._parse_key(key))

    def __setitem__(self, key, value):
        keypath_util.check_keys(value, self._keypath_separator)
        super().__setitem__(self._parse_key(key), value)

    def __setstate__(self, state):
        super().__setstate__(state)
        self._keypath_separator = state["_keypath_separator"]

    def _parse_key(self, key):
        keys = keypath_util.parse_keys(key, self._keypath_separator)
        keys_count = len(keys)
        if keys_count == 0:
            return None
        elif keys_count == 1:
            return keys[0]
        return keys

    @classmethod
    def fromkeys(cls, sequence, value=None):
        d = cls()
        for key in sequence:
            d[key] = value
        return d

    def get(self, key, default=None):
        return super().get(self._parse_key(key), default)

    def pop(self, key, *args):
        return super().pop(self._parse_key(key), *args)

    def update(self, other):
        keypath_util.check_keys(other, self._keypath_separator)
        super().update(other)
