"""
This module contains interfaces for storage classes
"""

import os
import abc
import array
from typing import Any, Iterator, TypeVar, Type, IO, Tuple, cast, List, Dict, Union, Iterable


import yaml
try:
    from yaml import CLoader as Loader, CDumper as Dumper  # type: ignore
except ImportError:
    from yaml import Loader, Dumper  # type: ignore


class IStorable(metaclass=abc.ABCMeta):
    """Interface for type, which can be stored"""

basic_types = {list, dict, tuple, set, type(None), int, str, bytes, bool, float}
for btype in basic_types:
    # pylint: disable=E1101
    IStorable.register(btype)  # type: ignore


ObjClass = TypeVar('ObjClass')


class ISimpleStorage(metaclass=abc.ABCMeta):
    """interface for low-level storage, which doesn't support serialization
    and can operate only on bytes"""

    @abc.abstractmethod
    def __setitem__(self, path: str, value: bytes) -> None:
        pass

    @abc.abstractmethod
    def __getitem__(self, path: str) -> bytes:
        pass

    @abc.abstractmethod
    def __delitem__(self, path: str) -> None:
        pass

    @abc.abstractmethod
    def __contains__(self, path: str) -> bool:
        pass

    @abc.abstractmethod
    def list(self, path: str) -> Iterator[Tuple[bool, str]]:
        pass

    @abc.abstractmethod
    def get_stream(self, path: str, mode: str = "rb+") -> IO:
        pass

    @abc.abstractmethod
    def sub_storage(self, path: str) -> 'ISimpleStorage':
        pass


class ISerializer(metaclass=abc.ABCMeta):
    """Interface for serialization class"""
    @abc.abstractmethod
    def pack(self, value: IStorable) -> bytes:
        pass

    @abc.abstractmethod
    def unpack(self, data: bytes) -> IStorable:
        pass


class FSStorage(ISimpleStorage):
    """Store all data in files on FS"""

    def __init__(self, root_path: str, existing: bool) -> None:
        self.root_path = root_path
        self.existing = existing
        if existing:
            if not os.path.isdir(self.root_path):
                raise IOError("No storage found at {!r}".format(root_path))

    def j(self, path: str) -> str:
        return os.path.join(self.root_path, path)

    def __setitem__(self, path: str, value: bytes) -> None:
        jpath = self.j(path)
        os.makedirs(os.path.dirname(jpath), exist_ok=True)
        with open(jpath, "wb") as fd:
            fd.write(value)

    def __delitem__(self, path: str) -> None:
        try:
            os.unlink(path)
        except FileNotFoundError:
            pass

    def __getitem__(self, path: str) -> bytes:
        with open(self.j(path), "rb") as fd:
            return fd.read()

    def __contains__(self, path: str) -> bool:
        return os.path.exists(self.j(path))

    def list(self, path: str = "") -> Iterator[Tuple[bool, str]]:
        jpath = self.j(path)
        for entry in os.scandir(jpath):
            if not entry.name in ('..', '.'):
                yield entry.is_file(), entry.name

    def get_stream(self, path: str, mode: str = "rb+") -> IO[bytes]:
        jpath = self.j(path)

        if "cb" == mode:
            create_on_fail = True
            mode = "rb+"
        else:
            create_on_fail = False

        try:
            fd = open(jpath, mode)
        except IOError:
            if not create_on_fail:
                raise
            fd = open(jpath, "wb")

        return cast(IO[bytes], fd)

    def sub_storage(self, path: str) -> 'FSStorage':
        return self.__class__(self.j(path), self.existing)


class YAMLSerializer(ISerializer):
    """Serialize data to yaml"""
    def pack(self, value: Any) -> bytes:
        if type(value) not in basic_types:
            for name, val in value.__dict__.items():
                if type(val) not in basic_types:
                    raise ValueError(("Can't pack {!r}. Attribute {} has value {!r} (type: {}), but only" +
                                      " basic types accepted as attributes").format(value, name, val, type(val)))
            value = value.__dict__
        return yaml.dump(value, Dumper=Dumper, encoding="utf8")

    def unpack(self, data: bytes) -> IStorable:
        return yaml.load(data, Loader=Loader)


class Storage:
    """interface for storage"""
    def __init__(self, storage: ISimpleStorage, serializer: ISerializer) -> None:
        self.storage = storage
        self.serializer = serializer

    def sub_storage(self, *path: str) -> 'Storage':
        return self.__class__(self.storage.sub_storage("/".join(path)), self.serializer)

    def __setitem__(self, path: Union[str, Iterable[str]], value: Any) -> None:
        if not isinstance(path, str):
            path = "/".join(path)

        self.storage[path] = self.serializer.pack(cast(IStorable, value))

    def __getitem__(self, path: Union[str, Iterable[str]]) -> IStorable:
        if not isinstance(path, str):
            path = "/".join(path)

        return self.serializer.unpack(self.storage[path])

    def __delitem__(self, path: Union[str, Iterable[str]]) -> None:
        if not isinstance(path, str):
            path = "/".join(path)

        del self.storage[path]

    def __contains__(self, path: Union[str, Iterable[str]]) -> bool:
        if not isinstance(path, str):
            path = "/".join(path)
        return path in self.storage

    def list(self, *path: str) -> Iterator[Tuple[bool, str]]:
        return self.storage.list("/".join(path))

    def set_array(self, value: array.array, *path: str) -> None:
        with self.get_stream("/".join(path), "wb") as fd:
            value.tofile(fd)  # type: ignore

    def get_array(self, typecode: str, *path: str) -> array.array:
        res = array.array(typecode)
        path_s = "/".join(path)
        with self.get_stream(path_s, "rb") as fd:
            fd.seek(0, os.SEEK_END)
            size = fd.tell()
            fd.seek(0, os.SEEK_SET)
            assert size % res.itemsize == 0, "Storage object at path {} contains no array of {} or corrupted."\
                .format(path_s, typecode)
            res.fromfile(fd, size // res.itemsize)  # type: ignore
        return res

    def append(self, value: array.array, *path: str) -> None:
        with self.get_stream("/".join(path), "cb") as fd:
            fd.seek(0, os.SEEK_END)
            value.tofile(fd)  # type: ignore

    def construct(self, path: str, raw_val: Dict, obj_class: Type[ObjClass]) -> ObjClass:
        "Internal function, used to construct user type from raw unpacked value"
        if obj_class in (int, str, dict, list, None):
            raise ValueError("Can't load into build-in value - {!r} into type {}")

        if not isinstance(raw_val, dict):
            raise ValueError("Can't load path {!r} into python type. Raw value not dict".format(path))

        if not all(isinstance(key, str) for key in raw_val.keys()):
            raise ValueError("Can't load path {!r} into python type.".format(path) +
                             "Raw not all keys in raw value is strings")

        obj = obj_class.__new__(obj_class)  # type: ObjClass
        obj.__dict__.update(raw_val)
        return obj

    def load_list(self, obj_class: Type[ObjClass], *path: str) -> List[ObjClass]:
        path_s = "/".join(path)
        raw_val = self[path_s]
        assert isinstance(raw_val, list)
        return [self.construct(path_s, val, obj_class) for val in cast(list, raw_val)]

    def load(self, obj_class: Type[ObjClass], *path: str) -> ObjClass:
        path_s = "/".join(path)
        return self.construct(path_s, cast(Dict, self[path_s]), obj_class)

    def get_stream(self, path: str, mode: str = "r") -> IO:
        return self.storage.get_stream(path, mode)

    def get(self, path: Union[str, Iterable[str]], default: Any = None) -> Any:
        if not isinstance(path, str):
            path = "/".join(path)

        try:
            return self[path]
        except Exception:
            return default

    def __enter__(self) -> 'Storage':
        return self

    def __exit__(self, x: Any, y: Any, z: Any) -> None:
        return


def make_storage(url: str, existing: bool = False) -> Storage:
    return Storage(FSStorage(url, existing), YAMLSerializer())

