from typing import (
    Callable,
    Union,
    Dict,
)

from messagebus import (
    Message,
    AckMessage,
    MessageBusException, Event,
)
from ._SyncEventMock import SyncEventMock
from ._SyncEventRequestValidator import SyncEventRequestValidator


class SyncEventMockBuilder(object):
    def __init__(
        self,
        subject: str,
    ):
        self.subject = subject
        self.event_type = None
        self.data_validator = None
        self.headers_validator = None
        self.callback = None
        self.response = AckMessage()

    def with_event_type(self, event_type: str):
        self.event_type = event_type
        return self

    def with_data(self, data_validator: Callable[[bytes], bool]):
        self.data_validator = data_validator
        return self

    def with_headers(self, headers_validator: Callable[[Dict[str, str]], bool]):
        self.headers_validator = headers_validator
        return self

    def with_callback(self, callback: Callable[[Event], bool]):
        self.callback = callback
        return self

    def will_reply_with(self, response: Union[Message, MessageBusException]):
        self.response = response
        return self

    def build(self):
        return SyncEventMock(
            request_validator=SyncEventRequestValidator(
                subject=self.subject,
                event_type=self.event_type,
                data_validator=self.data_validator,
                headers_validator=self.headers_validator,
                callback=self.callback,
            ),
            response=self.response
        )
