from typing import Any, List, Tuple

from django.conf import settings

from mdb_redis.sentinel import MdbSentinel


class Redis:
    def __init__(self, hosts: List[Tuple[str, int]], cluster: str, timeout: int = None, **kwargs):
        self.cluster = cluster
        self.sentinel = MdbSentinel(hosts, **kwargs)

    def get(self, key: str, default: Any = None) -> Any:
        redis = self.sentinel.slave_for(self.cluster)
        if redis:
            result = redis.get(key)
            if result is not None:
                result = result.decode()
            else:
                result = default
            return result

    def set(self, key: str, value: Any) -> None:
        redis = self.sentinel.master_for(self.cluster)
        if redis:
            redis.set(key, value.encode())

    def hget(self, name: str, key: str, default: Any = None) -> Any:
        redis = self.sentinel.slave_for(self.cluster)
        if redis:
            result = redis.hget(name, key)
            if result is not None:
                result = result.decode()
            else:
                result = default
            return result

    def hset(self, name: str, key: str, value: Any) -> None:
        redis = self.sentinel.master_for(self.cluster)
        if redis:
            redis.hset(name, key, value.encode())

    def delete(self, *keys: str):
        redis = self.sentinel.master_for(self.cluster)
        if redis and keys:
            redis.delete(*keys)

    def keys(self, pattern: str = '*'):
        redis = self.sentinel.slave_for(self.cluster)
        if redis:
            return [key.decode() for key in redis.keys(pattern)]

    def incr(self, key: str):
        redis = self.sentinel.master_for(self.cluster)
        if redis:
            redis.incr(key)

    def hincrby(self, name: str, key: str):
        redis = self.sentinel.master_for(self.cluster)
        if redis:
            redis.hincrby(name, key)

    def hgetall(self, name: str):
        redis = self.sentinel.master_for(self.cluster)
        if redis:
            return {key.decode(): value.decode() for key, value in redis.hgetall(name).items()}


redis = Redis(settings.REDIS_HOSTS, settings.REDIS_CLUSTER, password=settings.REDIS_PASSWORD, db=settings.REDIS_DB)
