"""Redis 缓存后端: 笨 KV(CacheBackend 契约);redis 是 optional extra。

降级不在这里做——本类忠实上抛异常,静默降级是 CacheMW 的职责(算法一份)。
"""

from __future__ import annotations

from typing import Any

try:
    import redis.asyncio as aioredis
except ImportError as _exc:  # pragma: no cover - 依赖缺失路径
    aioredis = None
    _IMPORT_ERROR = _exc
else:
    _IMPORT_ERROR = None


class RedisCache:
    """基于 redis.asyncio 的 KV;value 为 JSON 字符串,TTL 由调用方传入。"""

    def __init__(self, client: Any) -> None:
        if aioredis is None:
            raise ImportError(
                "Redis 缓存后端需要 redis 包: pip install 'polygateway[redis]'"
            ) from _IMPORT_ERROR
        self._client = client
        # 注入的客户端归注入方管理: 关掉它会弄死共享同一连接的其他组件
        # (与 RedisLimiter/RedisGate 同一纪律)
        self._owns_client = False

    @classmethod
    def from_url(cls, url: str) -> RedisCache:
        """自建并持有 Redis 客户端(aclose 时代关);共享后端请直接注入 client。"""
        if aioredis is None:
            raise ImportError(
                "Redis 缓存后端需要 redis 包: pip install 'polygateway[redis]'"
            ) from _IMPORT_ERROR
        cache = cls(aioredis.from_url(url, decode_responses=True))
        cache._owns_client = True
        return cache

    async def get(self, key: str) -> str | None:
        return await self._client.get(key)

    async def set(self, key: str, value: str, ttl_s: int) -> None:
        await self._client.set(key, value, ex=ttl_s)

    async def aclose(self) -> None:
        """幂等释放自建客户端;注入的客户端归注入方管理。"""
        if self._owns_client:
            self._owns_client = False
            await self._client.aclose()
