import logging

from messagebus import DefaultToken
from zeromqthreadpool import WorkerThread

from ._MessageDecoder import MessageDecoder

logger = logging.getLogger("ZeroMqMessageHandler.HandleMessageWorkerThread")


class HandleMessageWorkerThread(WorkerThread):
    def __init__(self, context, worker_address, idle_timeout, identity, message_bus, message_handler_builder):
        super(HandleMessageWorkerThread, self).__init__(context, worker_address, idle_timeout, identity)
        self.message_handler_builder = message_handler_builder
        self.message_bus = message_bus

    def do_work(self, data):
        message = MessageDecoder.parse_message(data)
        if message is None:
            return b""

        message_handler = None
        if message.token == DefaultToken.TK_EVT_EVENT:
            event = MessageDecoder.parse_event(message.data)
            event.headers = message.headers
            try:
                message_handler = self.message_handler_builder.build_message_handler(None, event)
                message_handler.handle_event(self.message_bus, event)
                return MessageDecoder.format_message(self.message_bus.get_reply())
            except:
                logger.exception("Error handling event: {} - {}".format(event.subject, event.event_type))
                return b""
            finally:
                if message_handler is not None:
                    self.message_handler_builder.destroy_message_handler(message_handler)
        else:
            try:
                message_handler = self.message_handler_builder.build_message_handler(message, None)
                message_handler.handle_message(self.message_bus, message)
                return MessageDecoder.format_message(self.message_bus.get_reply())
            except:
                logger.exception("Error handling message: {} - {}".format(message.token, message.data_type))
                return b""
            finally:
                if message_handler is not None:
                    self.message_handler_builder.destroy_message_handler(message_handler)

    def dispose(self):
        pass
