# generated by fastapi-codegen:
#   filename:  connector
#   timestamp: 2025-08-06T07:59:35+00:00

# generated by fastapi-codegen:
#   filename:  connector
#   timestamp: 2025-07-30T11:25:18+00:00

import logging
from typing import Any, Callable, Dict, Generic, Optional, TypeVar

from fastapi import HTTPException
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse

T = TypeVar('T', bound=Callable)


logger = logging.getLogger(__name__)


class HandlerRegistry(Generic[T]):
    """A more sophisticated handler registry with decorator support and logging."""

    def __init__(self, name: str = "default"):
        self.name = name
        self._handlers: Dict[str, T] = {}

    def register(self, tag: str) -> Callable[[T], T]:
        """Decorator to register a handler.

        Usage:
            registry = HandlerRegistry()

            @registry.register("my_handler")
            def my_handler():
                pass
        """

        def decorator(handler: T) -> T:
            self.set_handler(tag, handler)
            return handler

        return decorator

    def set_handler(self, tag: str, handler: T) -> None:
        """Register a handler for the given tag."""
        if not tag:
            raise ValueError("Tag cannot be empty")
        if not callable(handler):
            raise TypeError("Handler must be callable")

        if tag in self._handlers:
            logger.warning(
                f"Overriding existing handler for tag '{tag}' in registry '{self.name}'"
            )

        self._handlers[tag] = handler()
        logger.debug(
            f"Registered handler '{handler.__name__}' for tag '{tag}' in registry '{self.name}'"
        )

    def get_handler(self, tag: str) -> Optional[T]:
        """Retrieve a handler for the given tag."""
        handler = self._handlers.get(tag)
        if handler is None:
            logger.warning(
                f"No handler found for tag '{tag}' in registry '{self.name}'"
            )
        return handler

    def has_handler(self, tag: str) -> bool:
        """Check if a handler exists for the given tag."""
        return tag in self._handlers

    def remove_handler(self, tag: str) -> bool:
        """Remove a handler for the given tag."""
        if tag in self._handlers:
            del self._handlers[tag]
            logger.debug(f"Removed handler for tag '{tag}' from registry '{self.name}'")
            return True
        return False

    def clear_handlers(self) -> None:
        """Remove all registered handlers."""
        count = len(self._handlers)
        self._handlers.clear()
        logger.debug(f"Cleared {count} handlers from registry '{self.name}'")

    def get_all_tags(self) -> list[str]:
        """Get all registered tags."""
        return list(self._handlers.keys())

    def __len__(self) -> int:
        """Return the number of registered handlers."""
        return len(self._handlers)

    def __contains__(self, tag: str) -> bool:
        """Check if a tag is registered (supports 'in' operator)."""
        return tag in self._handlers

    def __repr__(self) -> str:
        return f"HandlerRegistry(name='{self.name}', handlers={len(self._handlers)})"


# Global instance for backward compatibility
default_registry = HandlerRegistry("global")


# Convenience functions that delegate to the global registry
def set_handler(tag: str, handler: Callable) -> None:
    """Register a handler globally."""
    default_registry.set_handler(tag, handler)


def get_handler(tag: str) -> Optional[Callable]:
    """Get a handler from the global registry."""
    return default_registry.get_handler(tag)


def register(tag: str) -> Callable:
    """Decorator to register a handler globally."""
    return default_registry.register(tag)


def call_handler(tag: str, func_name: str, *args, **kwargs) -> Any:
    """Decorator to call a handler."""

    handler = default_registry.get_handler(tag)
    if handler:
        handler_func = getattr(handler, func_name, None)
        if not handler_func:
            logger.warning(f"No handler found for '{tag}#{func_name}'")
        else:
            content = handler_func(*args, **kwargs)
            if content:
                return JSONResponse(content=jsonable_encoder(content), status_code=200)
    raise HTTPException(status_code=404, detail=f"failed to handle {tag}#{func_name}")
