"""EventBus Protocol definition.

Defines the :class:`EventBus` structural interface that all event-bus
implementations must satisfy.  Domain services depend only on this
protocol, never on concrete implementations, keeping the domain layer
decoupled from infrastructure choices.

Based on:
    - docs/specification.md §Event-Driven Architecture
    - Forgejo issue #473
"""

from __future__ import annotations

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

from cleveragents.infrastructure.events.models import DomainEvent
from cleveragents.infrastructure.events.types import EventType


@runtime_checkable
class EventBus(Protocol):
    """Structural interface for emitting and subscribing to domain events.

    Implementations may be reactive (RxPY), logging-only, or in-memory
    stubs.  Callers (domain services) depend on this protocol and receive
    the concrete implementation through dependency injection.
    """

    def emit(self, event: DomainEvent) -> None:
        """Publish *event* to all registered subscribers.

        Args:
            event: The :class:`DomainEvent` to publish.
        """
        ...

    def subscribe(
        self,
        event_type: EventType,
        handler: Callable[[DomainEvent], None],
    ) -> None:
        """Register *handler* to receive events of *event_type*.

        Args:
            event_type: The :class:`EventType` to listen for.
            handler: Callable invoked synchronously for each matching event.
        """
        ...


__all__ = ["EventBus"]
