"""Protocol-neutral media contracts used inside pipelines."""

from __future__ import annotations

from dataclasses import dataclass, field


@dataclass(frozen=True, slots=True)
class CameraIntrinsics:
    fx: float
    fy: float
    cx: float
    cy: float
    coefficients: tuple[float, ...] = ()


@dataclass(frozen=True, slots=True)
class ImageFrame:
    """An encoded packet or decoded image buffer.

    ``codec`` is ``"none"`` for decoded/raw frames.  Encoded video packets
    retain key-frame metadata so a stateful decoder can be used downstream.
    """

    data: bytes
    width: int
    height: int
    pixel_format: str
    codec: str = "none"
    is_key_frame: bool = False
    intrinsics: CameraIntrinsics | None = None

    @property
    def is_encoded(self) -> bool:
        return self.codec.lower() not in {"", "none", "raw"}


@dataclass(frozen=True, slots=True)
class EncodedImage:
    """A compressed image ready to cross a platform boundary."""

    data: bytes = field(repr=False)
    media_type: str
    width: int
    height: int

    def __post_init__(self) -> None:
        if not isinstance(self.data, bytes) or not self.data:
            raise ValueError("encoded image data must be non-empty bytes")
        if not isinstance(self.media_type, str) or not self.media_type.strip():
            raise ValueError("encoded image media_type must be a non-empty string")
        if (
            isinstance(self.width, bool)
            or not isinstance(self.width, int)
            or self.width < 1
        ):
            raise ValueError("encoded image width must be a positive integer")
        if (
            isinstance(self.height, bool)
            or not isinstance(self.height, int)
            or self.height < 1
        ):
            raise ValueError("encoded image height must be a positive integer")


@dataclass(frozen=True, slots=True)
class AudioChunk:
    """A contiguous audio chunk independent of its transport protocol."""

    data: bytes
    sample_rate: int
    channels: int
    sample_format: str
    codec: str = "pcm"
    discontinuity: bool = False
