from abc import ABC, abstractmethod
from typing import Any


class CacheClient(ABC):
    """Abstract contract for all cache backends.

    Every method is ``async def``.  Backends that do not support a particular
    data structure raise :exc:`NotImplementedError` (the default).

    Connection lifecycle
    --------------------
    Clients that manage pooled connections should initialise them in
    :meth:`connect` and release them in :meth:`disconnect`.
    """

    # -- Connection lifecycle ------------------------------------------------

    @abstractmethod
    async def connect(self) -> None:
        """Open connections / pools."""
        ...

    @abstractmethod
    async def disconnect(self) -> None:
        """Close connections / pools."""
        ...

    @abstractmethod
    async def ping(self) -> bool:
        """Health check — return True if the backend is reachable."""
        ...

    # -- Key-Value operations -------------------------------------------------

    async def get(self, key: str) -> Any:
        raise NotImplementedError("get() is not supported for this client")

    async def set(self, key: str, value: Any, ttl: int | None = None) -> None:
        raise NotImplementedError("set() is not supported for this client")

    async def setnx(self, key: str, value: Any, ttl: int | None = None) -> bool:
        """Set *key* to *value* only if it does **not** already exist.

        Returns ``True`` if the key was set, ``False`` if it already existed.
        """
        raise NotImplementedError("setnx() is not supported for this client")

    async def delete(self, *keys: str) -> int:
        raise NotImplementedError("delete() is not supported for this client")

    async def exists(self, *keys: str) -> int:
        raise NotImplementedError("exists() is not supported for this client")

    async def expire(self, key: str, ttl: int) -> bool:
        raise NotImplementedError("expire() is not supported for this client")

    async def ttl(self, key: str) -> int:
        raise NotImplementedError("ttl() is not supported for this client")

    async def incr(self, key: str, amount: int = 1) -> int:
        raise NotImplementedError("incr() is not supported for this client")

    async def decr(self, key: str, amount: int = 1) -> int:
        raise NotImplementedError("decr() is not supported for this client")

    # -- Hash operations ------------------------------------------------------

    async def hget(self, key: str, field: str) -> Any:
        raise NotImplementedError("hget() is not supported for this client")

    async def hset(self, key: str, mapping: dict[str, Any]) -> int:
        raise NotImplementedError("hset() is not supported for this client")

    async def hgetall(self, key: str) -> dict[str, Any]:
        raise NotImplementedError("hgetall() is not supported for this client")

    async def hdel(self, key: str, *fields: str) -> int:
        raise NotImplementedError("hdel() is not supported for this client")

    async def hexists(self, key: str, field: str) -> bool:
        raise NotImplementedError("hexists() is not supported for this client")

    async def hkeys(self, key: str) -> list[str]:
        raise NotImplementedError("hkeys() is not supported for this client")

    async def hlen(self, key: str) -> int:
        raise NotImplementedError("hlen() is not supported for this client")

    # -- List operations ------------------------------------------------------

    async def lpush(self, key: str, *values: Any) -> int:
        raise NotImplementedError("lpush() is not supported for this client")

    async def rpush(self, key: str, *values: Any) -> int:
        raise NotImplementedError("rpush() is not supported for this client")

    async def lpop(self, key: str) -> Any:
        raise NotImplementedError("lpop() is not supported for this client")

    async def rpop(self, key: str) -> Any:
        raise NotImplementedError("rpop() is not supported for this client")

    async def lrange(self, key: str, start: int, stop: int) -> list[Any]:
        raise NotImplementedError("lrange() is not supported for this client")

    async def llen(self, key: str) -> int:
        raise NotImplementedError("llen() is not supported for this client")

    # -- Set operations -------------------------------------------------------

    async def sadd(self, key: str, *members: Any) -> int:
        raise NotImplementedError("sadd() is not supported for this client")

    async def srem(self, key: str, *members: Any) -> int:
        raise NotImplementedError("srem() is not supported for this client")

    async def smembers(self, key: str) -> list[Any]:
        raise NotImplementedError("smembers() is not supported for this client")

    async def sismember(self, key: str, member: Any) -> bool:
        raise NotImplementedError("sismember() is not supported for this client")

    async def scard(self, key: str) -> int:
        raise NotImplementedError("scard() is not supported for this client")

    # -- Sorted-set operations ------------------------------------------------

    async def zadd(self, key: str, mapping: dict[Any, float]) -> int:
        raise NotImplementedError("zadd() is not supported for this client")

    async def zrem(self, key: str, *members: Any) -> int:
        raise NotImplementedError("zrem() is not supported for this client")

    async def zrange(
        self, key: str, start: int, stop: int, withscores: bool = False
    ) -> list[Any]:
        raise NotImplementedError("zrange() is not supported for this client")

    async def zcard(self, key: str) -> int:
        raise NotImplementedError("zcard() is not supported for this client")

    # -- Utility --------------------------------------------------------------

    async def keys(self, pattern: str) -> list[str]:
        raise NotImplementedError("keys() is not supported for this client")

    async def flush(self) -> None:
        raise NotImplementedError("flush() is not supported for this client")
