import logging
from abc import abstractmethod
from typing import Dict, AsyncGenerator, Iterable

from mcp import types
from mcp.server.lowlevel import helper_types as low_types

from ..consts import consts

logger = logging.getLogger(consts.LOGGER_NAME)


class ResourceProvider:
    def __init__(self, scheme: str):
        self.scheme = scheme

    @abstractmethod
    async def list_resources(self, **kwargs) -> list[types.Resource]:
        pass

    @abstractmethod
    async def read_resource(self, uri: types.AnyUrl, **kwargs) -> [str | bytes | Iterable[low_types.ReadResourceContents]]:
        pass


_all_resource_providers: Dict[str, ResourceProvider] = {}


async def list_resources(**kwargs) -> AsyncGenerator[types.Resource, None]:
    if len(_all_resource_providers) == 0:
        return

    for provider in _all_resource_providers.values():
        resources = await provider.list_resources(**kwargs)
        for resource in resources:
            yield resource
    return


async def read_resource(uri: types.AnyUrl, **kwargs) -> [str | bytes | Iterable[low_types.ReadResourceContents]]:
    if len(_all_resource_providers) == 0:
        return ""

    provider = _all_resource_providers.get(uri.scheme)
    return await provider.read_resource(uri=uri, **kwargs)


def register_resource_provider(provider: ResourceProvider):
    """注册工具，禁止重复名称"""
    name = provider.scheme
    if name in _all_resource_providers:
        raise ValueError(f"Resource Provider {name} already registered")
    _all_resource_providers[name] = provider


__all__ = [
    "ResourceProvider",
    "list_resources",
    "read_resource",
    "register_resource_provider",
]
