from __future__ import annotations

import asyncio
import inspect
from dataclasses import dataclass, field
from typing import Any, Awaitable, Callable


@dataclass
class LazyAsyncGateway:
    """Lazy async gateway builder.

    Used when gateway construction requires awaiting (e.g. creating an aiohttp transport),
    but the public API wants to return a service client immediately.
    """

    builder: Callable[[], Awaitable[Any]] = field(repr=False)
    _gateway: Any | None = field(default=None, repr=False)
    _lock: asyncio.Lock | None = field(default=None, repr=False)

    async def _get(self) -> Any:  # noqa: ANN401
        if self._gateway is not None:
            return self._gateway
        if self._lock is None:
            self._lock = asyncio.Lock()
        async with self._lock:
            if self._gateway is None:
                self._gateway = await self.builder()
        return self._gateway

    def __getattr__(self, name: str) -> Any:  # noqa: ANN401
        async def _wrapped(*args: Any, **kwargs: Any) -> Any:
            gw = await self._get()
            target = getattr(gw, name)
            out = target(*args, **kwargs)
            if inspect.isawaitable(out):
                return await out
            return out

        return _wrapped

    async def aclose(self) -> None:
        gw = self._gateway
        if gw is None:
            return
        aclose = getattr(gw, "aclose", None)
        if callable(aclose):
            out = aclose()
            if inspect.isawaitable(out):
                await out


__all__ = ["LazyAsyncGateway"]

