import abc

from onesecondtrader import events, messaging


class BrokerBase(messaging.Subscriber):
    """
    Abstract base class for broker components.

    A broker component receives order-related request events from the event bus and translates them into actions against an external execution venue or simulated environment.
    Responses to these requests are published back onto the event bus.

    This class defines the event-handling interface and subscription logic common to all broker implementations.
    """

    def __init__(self, event_bus: messaging.EventBus) -> None:
        """
        Initialize the broker and subscribe to order request events.

        Parameters:
            event_bus:
                Event bus used for receiving order requests and publishing response events.
        """
        super().__init__(event_bus)

        self._subscribe(
            events.requests.OrderSubmissionRequest,
            events.requests.OrderCancellationRequest,
            events.requests.OrderModificationRequest,
        )

    @abc.abstractmethod
    def connect(self) -> None:
        """
        Establish a connection to the external broker API.
        For simulated broker, this method is a no-op.

        Implementations are responsible for initializing any external resources required to submit, modify, or cancel orders.
        """
        pass

    def disconnect(self) -> None:
        """
        Disconnect the external broker API and stop event processing.
        For simulated broker, this method is a no-op.

        This method shuts down the subscriber and releases associated resources.
        """
        self.shutdown()

    def _on_event(self, event: events.EventBase) -> None:
        """
        Dispatch incoming order-related events to the appropriate handler.

        Parameters:
            event:
                Incoming event received from the event bus.
        """
        match event:
            case events.requests.OrderSubmissionRequest() as submit_order:
                self._on_submit_order(submit_order)
            case events.requests.OrderCancellationRequest() as cancel_order:
                self._on_cancel_order(cancel_order)
            case events.requests.OrderModificationRequest() as modify_order:
                self._on_modify_order(modify_order)
            case _:
                return

    @abc.abstractmethod
    def _on_submit_order(self, event: events.requests.OrderSubmissionRequest) -> None:
        """
        Handle an order submission request.

        Parameters:
            event:
                Order submission request event.
        """
        pass

    @abc.abstractmethod
    def _on_cancel_order(self, event: events.requests.OrderCancellationRequest) -> None:
        """
        Handle an order cancellation request.

        Parameters:
            event:
                Order cancellation request event.
        """
        pass

    @abc.abstractmethod
    def _on_modify_order(self, event: events.requests.OrderModificationRequest) -> None:
        """
        Handle an order modification request.

        Parameters:
            event:
                Order modification request event.
        """
        pass

    def _respond(self, response_event: events.responses.ResponseBase) -> None:
        """
        Publish a response event to the event bus.

        Parameters:
            response_event:
                Response event generated by the broker.
        """
        self._publish(response_event)
