from redis.client import Redis
from .tools._Entity import _Entity
from .tools.EntityAttributes import EntityAttributes
from .tools.EntityCollection import EntityCollection
from .tools.Mutex import Mutex
from .Keys import KEY_CONTEXT, KEY_TOPOLOGIES
from .Topology import Topology

VALIDATORS = {}

class Context(_Entity):
    def __init__(self, context_uuid : str, redis_client: Redis):
        self.__redis_client = redis_client
        self.__mutex = Mutex(self.__redis_client)
        self.__acquired = False
        self.__owner_key = None
        self.__entity_key = KEY_CONTEXT.format(context_uuid=context_uuid)
        super().__init__(context_uuid, self)
        self.context_uuid = self.get_uuid()
        self.attributes = EntityAttributes(self, KEY_CONTEXT, validators=VALIDATORS)
        self.topologies = EntityCollection(self, KEY_TOPOLOGIES)

    def get_parent(self): return(self)
    def get_context(self): return(self)
    def get_redis_client(self): return(self.__redis_client)

    def __enter__(self):
        self.__acquired,self.__owner_key = self.__mutex.acquire(self.__entity_key, owner_key=self.__owner_key)
        if not self.__acquired: raise Exception('Unable to acquire {}'.format(self.__entity_key))
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if not self.__acquired: return
        self.__mutex.release(self.__entity_key, self.__owner_key)

    def topology(self, topology_uuid : str) -> Topology:
        return Topology(topology_uuid, self)
