import json
import os
import os.path as path

from .generic import KeyStorage, UnknownKeyName
from .memory import MemoryKeyStorage


__all__ = [
    'FilesKeyStorage',
]


class FilesKeyStorage(KeyStorage):
    """ Files-based keys storage """

    def __init__(self, keys_path, files_suffix='.json'):
        super(FilesKeyStorage, self).__init__()
        self._root = keys_path
        self._suffix = files_suffix
        self._cache = {}

    def _get_file_storage(self, key_name):
        if key_name in self._cache:
            return self._cache[key_name]
        file_path = path.join(self._root, key_name + self._suffix)
        if not path.exists(file_path):
            raise UnknownKeyName(key_name)
        with open(file_path, 'r') as file:
            file_storage = MemoryKeyStorage(keys=json.load(file))
        self._cache[key_name] = file_storage
        return file_storage

    def _iter_key_names(self):
        for key_name in self._cache.keys():
            yield key_name
        if not path.exists(self._root):
            raise StopIteration()
        for file_name in os.listdir(self._root):
            full_name = path.join(self._root, file_name)
            if path.isdir(full_name) or not file_name.endswith(self._suffix):
                continue
            key_name = file_name[:-len(self._suffix)]
            if key_name not in self._cache:
                yield key_name

    def __getitem__(self, key):
        return self._get_file_storage(key)

    def __iter__(self):
        for key in self._iter_key_names():
            yield key

    def __len__(self):
        return len(list(self._iter_key_names()))
