import six
if six.PY2:
    from collections import Mapping
else:
    from collections.abc import Mapping


__all__ = [
    'UnknownKeyName',
    'KeyStorage',
]


class UnknownKeyName(KeyError):
    def __init__(self, key_name):
        super(UnknownKeyName, self).__init__()
        self.key_name = key_name

    def __str__(self):
        return 'Unknown key name %s' % self.key_name


class KeyStorage(Mapping):
    """ Base class for accessing keys from single namespace """

    def find_key(self, *path, **kwargs):
        assert not any(k != 'default' for k in kwargs)
        has_default = 'default' in kwargs
        default = kwargs.get('default', None)

        node = self
        try:
            for path_item in path:
                node = node[path_item]
            else:
                return node
        except UnknownKeyName:
            if has_default:
                return default
            else:
                raise

    def __getitem__(self, key):
        raise NotImplementedError()

    def __iter__(self):
        raise NotImplementedError()

    def __len__(self):
        raise NotImplementedError()
