import contextlib
import typing

from redis import Redis
from redis.asyncio import Redis as AsyncRedis
from starlette_dispatch import VariableResolver

from kupala.applications import AppConfig, Kupala


class RedisIntegration:
    def __init__(self, redis_client: Redis) -> None:
        self.redis = redis_client

    @contextlib.asynccontextmanager
    async def initialize(self, app: Kupala) -> typing.AsyncGenerator[None, None]:
        async with self.redis as redis:
            yield {"redis": redis}

    def configure_application(self, app_config: AppConfig) -> None:
        app_config.state["redis"] = self
        app_config.initializers.append(self.initialize)
        app_config.dependency_resolvers[Redis] = VariableResolver(self.redis)
        app_config.dependency_resolvers[AsyncRedis] = VariableResolver(self.redis)

    @classmethod
    def of(cls, app: Kupala) -> typing.Self:
        return app.state.redis
