"""llmpm.core.server — OpenAI-compatible HTTP server for loaded models.

Public API::

    from llmpm.core import server

    server.start(
        model_id     = "owner/my-model",
        infer        = my_infer_fn,
        infer_stream = my_stream_fn,
    )

Unsupported endpoints return HTTP 501 automatically.
"""
from __future__ import annotations

from http.server import ThreadingHTTPServer

from ._context import HandlerContext
from ._handler import _Handler
from ._types import (
    EmbedFn,
    InferFn,
    InferImageEditFn,
    InferImageFn,
    InferStreamFn,
    SynthesizeFn,
    TranscribeFn,
)

__all__ = [
    "start",
    "HandlerContext",
    "InferFn",
    "InferStreamFn",
    "EmbedFn",
    "InferImageFn",
    "InferImageEditFn",
    "TranscribeFn",
    "SynthesizeFn",
]


def _make_handler(ctx: HandlerContext) -> type:
    """Return a request-handler class bound to *ctx*."""

    class _BoundHandler(_Handler):
        _context = ctx

    _BoundHandler.__name__ = "_BoundHandler"
    return _BoundHandler


def start(
    model_id: str,
    infer: InferFn | None = None,
    *,
    host: str = "0.0.0.0",
    port: int = 8080,
    default_max_tokens: int = 128_000,
    infer_stream: InferStreamFn | None = None,
    embed: EmbedFn | None = None,
    infer_image: InferImageFn | None = None,
    infer_image_edit: InferImageEditFn | None = None,
    transcribe: TranscribeFn | None = None,
    synthesize: SynthesizeFn | None = None,
    category: str = "text-generation",
) -> None:
    """Start a blocking ThreadingHTTPServer for the given model.

    Pass only the callbacks your backend supports — unsupported endpoints
    return HTTP 501.  This call blocks until interrupted (Ctrl-C).
    """
    ctx = HandlerContext(
        model_id=model_id,
        default_max_tokens=default_max_tokens,
        category=category,
        infer=infer,
        infer_stream=infer_stream,
        embed=embed,
        infer_image=infer_image,
        infer_image_edit=infer_image_edit,
        transcribe=transcribe,
        synthesize=synthesize,
    )
    handler = _make_handler(ctx)
    httpd   = ThreadingHTTPServer((host, port), handler)
    httpd.serve_forever()
