import logging, json, os, redis
#from .context_api.Context import Context

LOGGER = logging.getLogger(__name__)

# 60.0 seconds (aprox) in incremental steps from 0.002 till 29.99 seconds
RETRY_DELAY_INITIAL = 0.002
RETRY_DELAY_INCREMENT = 1.831
MAX_RETRIES = 15

URL_TEMPLATE = 'redis://{host}:{port}/{dbid}'

FILEPATH = 'data/topo_nsfnet.json'

class RedisDatabase:
    def __init__(self, **parameters):
        host = os.environ.get('REDISDB_SERVICE_HOST')
        if(host is None): raise Exception('EnvironmentVariable(REDISDB_SERVICE_HOST) not found')
        port = os.environ.get('REDISDB_SERVICE_PORT')
        if(port is None): raise Exception('EnvironmentVariable(REDISDB_SERVICE_PORT) not found')
        dbid = os.environ.get('REDISDB_DATABASE_ID')
        if(dbid is None): raise Exception('EnvironmentVariable(REDISDB_DATABASE_ID) not found')
        self.redis_url = URL_TEMPLATE.format(host=host, port=port, dbid=dbid)
        self.handler = None
        self.connect() # initialize self.handler and connect to server

    def connect(self):
        self.handler = redis.Redis.from_url(self.redis_url)

    def close(self):
        if(self.handler is not None): del self.handler
        self.handler = None

    def get_topology(self):
        str_topology = self.handler.get('topology')
        if(str_topology is None):
            with open(FILEPATH, 'r') as f:
                json_topology = json.loads(f.read())
            str_topology = json.dumps(json_topology)
            self.handler.setnx('topology', str_topology)
            json_topology['source'] = 'redis missing, loaded from file'
        else:
            json_topology = json.loads(str_topology)
            json_topology['source'] = 'redis found!'
        return(json_topology)

    #def __getattr__(self, method_name):
    #    # Expose all methods in the database engine as owned
    #    def method(*args, **kwargs):
    #        num_try, delay = 1, RETRY_DELAY_INITIAL
    #        while num_try <= MAX_RETRIES:
    #            try:
    #                handler_method = getattr(self.handler, method_name, None)
    #                if handler_method is None: raise Exception('Redis does not support method({})'.format(method_name))
    #                return handler_method(*args, **kwargs)
    #            except ConnectionError: # as e:
    #                #if('Channel is closed' not in str(e)): raise
    #                self.connect() # Try to reconnect
    #                time.sleep(delay)
    #                num_try, delay = num_try + 1, delay * RETRY_DELAY_INCREMENT
    #        raise Exception('Unable to reconnect to Redis after {}'.format(MAX_RETRIES))
    #    return(method)
