# -*- coding: utf-8 -*-
from dialogmanager import DialogManager
from messagehandler import MessageHandlerBuilder
from messagepaymentprocessor import (
    CancelPaymentProcessor,
    CancelPaymentOrderProcessor,
    ConfirmFinishPaymentProcessor,
    FinishPaymentProcessor,
    GetElectronicTypesProcessor,
    TestConnectionProcessor,
    StartPaymentProcessor
)
from messageprocessor import DefaultMessageProcessorExecutorFactory, MessageProcessorMessageHandler
from messageprocessorutil import LoggingProcessorCallback
from messagetoken import MessageToken
from paymentrouter import PaymentRouter
from typing import Optional


class ElectronicPaymentMessageHandlerBuilder(MessageHandlerBuilder):
    def __init__(self, message_bus, config, logger):
        self.message_bus = message_bus
        self.config = config
        self.logger = logger

        self.message_handler = None
        self.dialog_manager = None  # type: Optional[DialogManager]
        self.payment_router = None  # type: Optional[PaymentRouter]

    def build_singletons(self):
        self.dialog_manager = DialogManager(self.message_bus, self.logger)
        self.payment_router = PaymentRouter(self.message_bus, self.dialog_manager, self.config, self.logger)

    def build_message_handler(self, _, __):
        event_processors = {}
        message_processors = {
            MessageToken.TK_ELECTRONIC_PAYMENT_ADD_PAYMENT: StartPaymentProcessor(self.payment_router),
            MessageToken.TK_ELECTRONIC_PAYMENT_CANCEL_PAYMENT: CancelPaymentProcessor(self.payment_router),
            MessageToken.TK_ELECTRONIC_PAYMENT_CANCEL_PAYMENT_ORDER: CancelPaymentOrderProcessor(self.payment_router),
            MessageToken.TK_ELECTRONIC_PAYMENT_FINISH_PAYMENT: FinishPaymentProcessor(self.payment_router),
            MessageToken.TK_ELECTRONIC_PAYMENT_CONFIRM_FINISH: ConfirmFinishPaymentProcessor(self.payment_router),
            MessageToken.TK_ELECTRONIC_PAYMENT_CONNECTIVITY_TEST: TestConnectionProcessor(self.payment_router),
            MessageToken.TK_ELECTRONIC_PAYMENT_GET_ELECTRONIC_TYPES: GetElectronicTypesProcessor(self.payment_router),
            MessageToken.TK_ELECTRONIC_PAYMENT_SEND_RESPONSE: self.dialog_manager
        }
        self.message_handler = MessageProcessorMessageHandler(
            event_processors,
            message_processors,
            DefaultMessageProcessorExecutorFactory([LoggingProcessorCallback(self.logger)]),
            None
        )
        return self.message_handler

    def destroy_message_handler(self, message_handler):
        pass  # no special handling necessary to destroy message handlers

    def destroy_singletons(self):
        self.payment_router.stop_processors()
