"""Adapter contract for optional real-time evidence stream emission."""

from __future__ import annotations

from collections.abc import Mapping
from dataclasses import dataclass, field
from typing import Any, Protocol, runtime_checkable

__all__ = [
    "TransparencyStreamAdapter",
    "TransparencyStreamReceipt",
    "normalise_transparency_stream_receipt",
]


@dataclass(frozen=True, slots=True)
class TransparencyStreamReceipt:
    """Acknowledgement metadata returned by a transparency stream adapter."""

    adapter: str
    event_id: str
    timestamp: str | None = None
    details: Mapping[str, Any] = field(default_factory=dict)

    def __post_init__(self) -> None:
        object.__setattr__(self, "adapter", _require_non_empty_string("adapter", self.adapter))
        object.__setattr__(self, "event_id", _require_non_empty_string("event_id", self.event_id))
        if self.timestamp is not None:
            object.__setattr__(
                self,
                "timestamp",
                _require_non_empty_string("timestamp", self.timestamp),
            )
        if not isinstance(self.details, Mapping):
            msg = "details must be a mapping."
            raise ValueError(msg)
        object.__setattr__(self, "details", dict(self.details))


@runtime_checkable
class TransparencyStreamAdapter(Protocol):
    """Contract for emitting transition evidence events to subscriber feeds."""

    def emit(
        self,
        *,
        event_payload: Mapping[str, Any],
    ) -> TransparencyStreamReceipt | Mapping[str, Any] | None:
        """Emit one event payload and optionally return an adapter acknowledgement."""


def normalise_transparency_stream_receipt(
    value: TransparencyStreamReceipt | Mapping[str, Any] | None,
) -> TransparencyStreamReceipt | None:
    """Normalise stream adapter acknowledgement values."""
    if value is None:
        return None
    if isinstance(value, TransparencyStreamReceipt):
        return value
    if not isinstance(value, Mapping):
        msg = "Transparency stream receipt must be a mapping, TransparencyStreamReceipt, or None."
        raise ValueError(msg)
    missing_fields = [name for name in ("adapter", "event_id") if name not in value]
    if missing_fields:
        msg = (
            f"Transparency stream receipt is missing required fields: {', '.join(missing_fields)}."
        )
        raise ValueError(msg)
    return TransparencyStreamReceipt(
        adapter=value["adapter"],
        event_id=value["event_id"],
        timestamp=value.get("timestamp"),
        details=value.get("details", {}),
    )


def _require_non_empty_string(field_name: str, value: Any) -> str:
    if not isinstance(value, str) or not value.strip():
        msg = f"{field_name} must be a non-empty string."
        raise ValueError(msg)
    return value.strip()
