from typing import Any, Callable, Dict
from ...engines._DatabaseEngine import _DatabaseEngine
from .EntityAttributes import EntityAttributes

class _Entity:
    def __init__(self, parent, entity_uuid : str, attributes_key : str,
                 attribute_validators : Dict[str, Callable[[Any], bool]],
                 attribute_transcoders : Dict[str, Dict[Any, Callable[[Any], Any]]]):
        if not isinstance(parent, _Entity):
            raise AttributeError('parent must be an instance of _Entity')
        if (not isinstance(entity_uuid, str)) or (len(entity_uuid) == 0):
            raise AttributeError('entity_uuid must be a non-empty instance of str')
        if (not isinstance(attributes_key, str)) or (len(attributes_key) == 0):
            raise AttributeError('attributes_key must be a non-empty instance of str')
        if not isinstance(attribute_validators, dict):
            raise AttributeError('attribute_validators must be an instance of dict')
        if not isinstance(attribute_transcoders, dict):
            raise AttributeError('attribute_transcoders must be an instance of dict')

        self._entity_uuid = entity_uuid
        self._parent = parent
        self._attributes = EntityAttributes(self, attributes_key, attribute_validators,
                                            transcoders=attribute_transcoders)

    @property
    def parent(self) -> '_Entity': return self._parent

    @property
    def database_engine(self) -> _DatabaseEngine: return self._parent.database_engine

    @property
    def attributes(self) -> EntityAttributes: return self._attributes

    def load(self):
        raise NotImplementedError()

    def create(self):
        raise NotImplementedError()

    def delete(self):
        raise NotImplementedError()

    def dump_id(self) -> Dict:
        raise NotImplementedError()

    def dump(self) -> Dict:
        raise NotImplementedError()
