"""HuggingFace-style client interface and registry.

`sage-libs` only defines integration interfaces and registry contracts.
Concrete clients must be provided by external implementation packages.
"""

from __future__ import annotations

from collections.abc import Callable
from typing import Any, Protocol, runtime_checkable


@runtime_checkable
class HuggingFaceClientProtocol(Protocol):
    """Protocol for HuggingFace-style text generation clients."""

    def generate(self, prompt: str | list[dict[str, str]], **kwargs: Any) -> str:
        """Generate output text for a prompt or chat-style message list."""


_HF_CLIENT_FACTORIES: dict[str, Callable[..., HuggingFaceClientProtocol]] = {}


def register_huggingface_client_factory(
    name: str,
    factory: Callable[..., HuggingFaceClientProtocol],
) -> None:
    """Register a HuggingFace-style client factory."""
    normalized = name.strip().lower()
    if not normalized:
        raise ValueError("Factory name must be a non-empty string")
    _HF_CLIENT_FACTORIES[normalized] = factory


def create_huggingface_client(name: str, **kwargs: Any) -> HuggingFaceClientProtocol:
    """Create a registered HuggingFace-style client by name."""
    normalized = name.strip().lower()
    if normalized not in _HF_CLIENT_FACTORIES:
        available = ", ".join(sorted(_HF_CLIENT_FACTORIES)) or "<none>"
        raise RuntimeError(f"Unknown HuggingFace client factory: {name!r}. Available: {available}.")

    client = _HF_CLIENT_FACTORIES[normalized](**kwargs)
    if not isinstance(client, HuggingFaceClientProtocol):
        raise TypeError(f"Factory {name!r} did not return a HuggingFaceClientProtocol")
    return client
