from logging import Logger

from messagehandler import MessageHandlerBuilder
from messageprocessor import MessageProcessorMessageHandler, DefaultMessageProcessorExecutorFactory, \
    LoggingProcessorCallback
from zeromqeventmanager import \
    TK_EVENT_MANAGER_UNSUBSCRIBE, \
    TK_EVENT_MANAGER_SUBSCRIBE, \
    TK_EVENT_MANAGER_PUBLISH, \
    TK_EVENT_MANAGER_KEEP_ALIVE, EventManager
from zeromqeventmanager.processor import SubscribeProcessor, PublishProcessor, KeepAliveProcessor
from zeromqmessagehandler import ZeroMqMessageBus

from ._ConfigKey import ConfigKey


class EventManagerMessageHandlerBuilder(MessageHandlerBuilder):
    def __init__(self, config, message_bus, logger):
        # type: (dict, ZeroMqMessageBus, Logger) -> None
        self.config = config
        self.message_bus = message_bus
        self.logger = logger
        self.event_manager = None  # type: EventManager

    def build_singletons(self):
        self.event_manager = EventManager(self.message_bus,
                                          self.config.get(ConfigKey.PUB_ADDRESS, None),
                                          self.config.get(ConfigKey.SUB_ADDRESS, None),
                                          self.config.get(ConfigKey.PULL_ADDRESS, None),
                                          clean_interval=5,
                                          sub_id_lifetime=30)

    def build_message_handler(self, message, event):
        handled_tokens = {
            TK_EVENT_MANAGER_SUBSCRIBE: SubscribeProcessor(self.event_manager),
            TK_EVENT_MANAGER_UNSUBSCRIBE: None,
            TK_EVENT_MANAGER_PUBLISH: PublishProcessor(self.event_manager),
            TK_EVENT_MANAGER_KEEP_ALIVE: KeepAliveProcessor(self.event_manager)
        }
        return MessageProcessorMessageHandler(
            None,
            handled_tokens,
            None,
            executor_factory=DefaultMessageProcessorExecutorFactory([LoggingProcessorCallback(self.logger)]),
            logger=self.logger)

    def destroy_message_handler(self, message_handler):
        pass

    def destroy_singletons(self):
        if self.event_manager is not None:
            self.event_manager.stop()
