from typing import Dict

from ._Message import Message
from ._DefaultToken import DefaultToken


class Event(object):
    def __init__(
        self,                   # type: Event
        subject,                # type: str
        event_type=None,        # type: str
        data=None,              # type: bytes
        source=0,               # type: int
        synchronous=False,      # type: bool
        timeout=-1,             # type: int
        headers=None,           # type: Dict[str, str]
        ttl=-1,                 # type: int
    ):
        # type: (...) -> None
        self.subject = subject
        self.event_type = event_type
        self.source = source
        self.data = data
        self.synchronous = synchronous
        self.timeout = timeout
        self.headers = headers if headers is not None else {}
        self.ttl = ttl

        self.imp_message = None

    def __str__(self):
        # type: () -> str
        return str({
            "subject": self.subject,
            "event_type": self.event_type,
            "synchronous": self.synchronous,
            "timeout": self.timeout,
            "headers": self.headers,
            "ttl": self.ttl,
        })

    @staticmethod
    def build_from_message(
        message,        # type: Message
    ):
        # type: (...) -> Event

        if message.token != DefaultToken.TK_EVT_EVENT:
            raise RuntimeError("Can only convert event messages")

        split_data = message.data.split(b"\0")
        event_data = split_data[0]
        subject = split_data[1].decode("utf-8")
        event_type = split_data[2].decode("utf-8")
        sync = split_data[3] == b"true"

        return Event(
            subject=subject,
            event_type=event_type,
            data=event_data,
            synchronous=sync,
            headers=message.headers,
        )

    def convert_to_message(
        self,       # type: Event
    ):
        # type: (...) -> Message

        data = b""
        if self.data is not None:
            data += self.data
        data += b"\0"
        data += self.subject.encode("utf-8") + b"\0"
        if self.event_type is not None:
            data += self.event_type.encode("utf-8")
        data += b"\0"
        data += b"true" if self.synchronous else b"false"

        return Message(
            token=DefaultToken.TK_EVT_EVENT,
            data=data,
            headers=self.headers,
        )
