import logging
from typing import List, Set
from .backend._Backend import _Backend
from .fields.PrimaryKeyField import PrimaryKeyField
from .model.Model import Model
from .Exceptions import MutexException

LOGGER = logging.getLogger(__name__)

class _Database(Model):
    def __init__(self, backend : _Backend):
        if not isinstance(backend, _Backend):
            str_class_path = '{}.{}'.format(_Backend.__module__, _Backend.__name__)
            raise AttributeError('backend must inherit from {}'.format(str_class_path))
        self._backend = backend
        super().__init__(self)
        self._acquired = False
        self._owner_key = None

    @property
    def parent(self) -> '_Database': return self

    @property
    def backend(self) -> _Backend: return self._backend

    @property
    def backend_key(self) -> str: return ''

    def __enter__(self) -> '_Database':
        self._acquired, self._owner_key = self._backend.lock()
        if not self._acquired: raise MutexException('Unable to acquire database lock')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb) -> None:
        self._backend.unlock(self._owner_key)

    def clear_all(self, keep_keys : Set[str] = set()) -> None:
        keys = self._backend.keys()
        for key in keys:
            if key in keep_keys: continue
            self._backend.delete(key)

    def dump(self) -> List[str]:
        entries = self._backend.dump()
        entries.sort()
        return ['[{:>4s}] {:100s} :: {}'.format(k_type, k_name, k_value) for k_name,k_type,k_value in entries]
