"""Backend-neutral abstraction for object-detection models."""

from __future__ import annotations

from abc import ABC, abstractmethod
from collections.abc import Sequence

from cmvr_edge_ai.contracts import Detection, ImageFrame


class DetectionModel(ABC):
    """A loaded detection model owned by one pipeline component.

    The interface is deliberately synchronous because most inference SDKs expose
    blocking APIs.  Pipeline operators must offload these methods to the shared
    thread executor (or to an explicitly owned process worker) instead of calling
    them directly on the asyncio event loop.
    """

    @abstractmethod
    def load(self) -> None:
        """Load weights and allocate model runtime resources."""

        raise NotImplementedError

    @abstractmethod
    def predict(
        self,
        frame: ImageFrame,
        labels: tuple[str, ...],
        confidence: float,
    ) -> Sequence[Detection]:
        """Detect selected ``labels`` in one decoded image frame.

        Implementations may use the selected labels to reduce backend
        post-processing, but callers still validate/filter returned detections at
        the common operator boundary.  ``confidence`` is in the inclusive
        ``[0, 1]`` range.
        """

        raise NotImplementedError

    @abstractmethod
    def close(self) -> None:
        """Release model resources; implementations should be idempotent."""

        raise NotImplementedError


__all__ = ["DetectionModel"]
