from logging import Logger
from memorycache import (
    CacheManager,
    PeriodBasedExpiration,
)
from typing import (
    Any,
    Dict,
    Optional,
)

from httpmessageprocessor import HttpMessageProcessorMessageHandler
from interactor.event import ElectronicPaymentEventInteractor
from interactor.route.electronic_payment.cache import CacheInteractor
from interactor.route.electronic_payment.cache.dto import CacheRequest
from interactor.route.customization.get_styles import GetStylesInteractor
from interactor.route.customization.get_styles.dto import GetStylesRequest
from interactor.route.loyalty.search_customer_info import SearchCustomerInfoInteractor
from interactor.route.loyalty.search_customer_info.dto import SearchCustomerInfoRequest
from interactor.route.menu.get_images import GetImagesInteractor
from interactor.route.menu.get_images.dto import GetImagesRequest
from interactor.route.menu.get_navigation import GetNavigationInteractor
from interactor.route.menu.get_navigation.dto import GetNavigationRequest
from interactor.route.menu.get_product_info import GetProductInfoInteractor
from interactor.route.menu.get_product_info.dto import GetProductInfoRequest
from interactor.route.menu.get_products import GetProductsInteractor
from interactor.route.menu.get_products.dto import GetProductsRequest
from interactor.route.menu.get_ruptured_products import GetRupturedProducts
from interactor.route.menu.get_ruptured_products.dto import GetRupturedProductsRequest
from interactor.route.menu.get_banners import GetBannersInteractor
from interactor.route.menu.get_banners.dto import GetBannersRequest
from interactor.route.menu.get_up_sell_part_codes import GetUpSellPartCodesInteractor
from interactor.route.menu.get_up_sell_part_codes.dto import GetUpSellPartCodesRequest
from interactor.route.order.add_items import AddItemsInteractor
from interactor.route.order.add_items.dto import AddItemsRequest
from interactor.route.order.add_properties import AddPropertiesInteractor
from interactor.route.order.add_properties.dto import AddPropertiesRequest
from interactor.route.order.apply_benefit import ApplyBenefitInteractor
from interactor.route.order.apply_benefit.dto import ApplyBenefitRequest
from interactor.route.order.apply_coupon import ApplyCouponInteractor
from interactor.route.order.apply_coupon.dto import ApplyCouponRequest
from interactor.route.order.cancel import OrderCancelInteractor
from interactor.route.order.cancel.dto import OrderCancelRequest
from interactor.route.order.change_items_quantity import ChangeItemsQuantityInteractor
from interactor.route.order.change_items_quantity.dto import ChangeItemsQuantityRequest
from interactor.route.order.close_shopping_cart import CloseShoppingCartInteractor
from interactor.route.order.close_shopping_cart.dto import CloseShoppingCartRequest
from interactor.route.order.create import OrderCreateInteractor
from interactor.route.order.create.dto import OrderCreateRequest
from interactor.route.order.delete_line import OrderDeleteLineInteractor
from interactor.route.order.delete_line.dto import OrderDeleteLineRequest
from interactor.route.order.finalize import OrderFinalizeInteractor
from interactor.route.order.finalize.dto import OrderFinalizeRequest
from interactor.route.order.get_coupons import GetCouponInteractor
from interactor.route.order.get_coupons.dto import GetCouponRequest
from interactor.route.order.get_detail import OrderGetDetailInteractor
from interactor.route.order.get_detail.dto import OrderGetDetailRequest
from interactor.route.order.save import OrderSaveInteractor
from interactor.route.order.save.dto import OrderSaveRequest
from interactor.route.payment.insert import OrderInsertPaymentInteractor
from interactor.route.payment.insert.dto import OrderInsertPaymentRequest
from interactor.route.order.reopen_shopping_cart import ReopenShoppingCartInteractor
from interactor.route.order.reopen_shopping_cart.dto import ReopenShoppingCartRequest
from interactor.route.order.remove_coupon import RemoveCouponInteractor
from interactor.route.order.remove_coupon.dto import RemoveCouponRequest
from interactor.route.payment.get_payment_types import GetPaymentTypesInteractor
from interactor.route.payment.get_payment_types.dto import GetPaymentTypesRequest
from interactor.route.electronic_payment.read_messages import ReadMessagesInteractor
from interactor.route.electronic_payment.read_messages.dto import ReadMessagesRequest
from interactor.route.electronic_payment.clear_messages import ClearMessagesInteractor
from interactor.route.electronic_payment.clear_messages.dto import ClearMessagesRequest
from interactor.route.electronic_payment.send_responses import SendResponsesInteractor
from interactor.route.electronic_payment.send_responses.dto import SendResponsesRequest
from interactor.route.customization.get_custom_images import GetCustomImagesInteractor
from interactor.route.customization.get_custom_images.dto import GetCustomImagesRequest
from interactor.route.customization.get_text import GetTextInteractor
from interactor.route.customization.get_text.dto import GetTextRequest
from interactor.route.peripheral.print_text import PrintTextInteractor
from interactor.route.peripheral.print_text.dto import PrintTextRequest
from interactor.route.peripheral.read_scanner import ReadScannerInteractor
from interactor.route.peripheral.read_scanner.dto import ReadScannerRequest
from interactor.route.store.get_status import GetStoreInteractor
from interactor.route.store.get_status.dto import GetStoreRequest
from interactor.route.store.get_config import GetStoreConfigInteractor
from interactor.route.store.get_config.dto import GetStoreConfigRequest
from interactor.route.payment.cancel import CancelPaymentInteractor
from interactor.route.payment.cancel.dto import CancelPaymentRequest
from mbcontextmessagehandler import MbContextMessageBus
from messagebus import Message, Event
from messagehandler import MessageHandlerBuilder, MessageHandler
from messageprocessor import (
    MessageProcessor,
    DefaultMessageProcessorExecutorFactory,
    MessageProcessorMessageHandler,
)
from messageprocessorutil import LoggingProcessorCallback
from model.config import Config
from model.event import ListenedEvents
from model.exception import (
    AuthValidationErrors,
    BadRequestError,
    ClientCustomError,
    ExternalServiceErrors,
    InUseError,
    NotAvailableError,
    NotFoundError,
    OperationErrors,
    ValidationError,
    BlockedError,
)
from model.response import Responses
from processor.event.electronic_payment import (
    ElectronicPaymentCloseDialogProcessor,
    ElectronicPaymentShowQRCodeProcessor,
    ElectronicPaymentShowChoicesProcessor,
    ElectronicPaymentShowInputProcessor,
    ElectronicPaymentShowMessageProcessor,
    ElectronicPaymentShowQuestionProcessor
)
from processor.event.pos_logger import PosLoggerAutoMappedMessageProcessor
from pyscripts_cache import PyscriptsCache
from repository import PosRepository
from services import (
    FiscalService,
    OrderService,
    ApiService,
    CouponService,
    ImagesService,
    PaymentService,
    ProductInfoService,
    PrinterService,
    LoyaltyService,
    NavigationService,
)
from services._ElectronicPaymentService import ElectronicPaymentService

from simplehttprouter import Route


class ServiceMessageHandlerBuilder(MessageHandlerBuilder):

    def __init__(self, logger, config, message_bus, flask_server=False):
        # type: (Logger, Config, MbContextMessageBus, bool) -> None

        self.navigation_service = None
        self.logger = logger
        self.config = config
        self.message_bus = message_bus
        self.flask_server = flask_server

        self.pos_repository = None
        self.fiscal_service = None
        self.coupon_service = None
        self.order_service = None
        self.api_service = None
        self.modifier_service = None
        self.images_service = None
        self.payment_service = None
        self.product_info_service = None
        self.printer_service = None
        self.loyalty_service = None
        self.electronic_payment_service = None

        self.pyscripts_cache = None

        self.cache_menu_ruptured_items = {"last_request_date": None, "data": None}
        self.cache_menu_products = None
        self.memory_cache = self._build_memory_cache()
        self.cache_menu_navigation = []
        self.electronic_messages = []

        self.callbacks = None
        self.message_handler = None
        self.logger_created = {}

    def build_singletons(self):
        # type: () -> None

        self.callbacks = [LoggingProcessorCallback(self.logger)]

        if self.flask_server:
            self.navigation_service = NavigationService(self.message_bus)
            self.printer_service = PrinterService(
                logger=self.logger,
                message_bus=self.message_bus,
            )
            self.pos_repository = PosRepository(
                self.message_bus,
                self.logger,
                self.config,
                self.navigation_service,
            )
            self.fiscal_service = FiscalService(
                message_bus=self.message_bus,
                logger=self.logger,
                pos_repository=self.pos_repository,
                printer_service=self.printer_service,
            )
            self.coupon_service = CouponService(self.message_bus, self.logger)
            self.pyscripts_cache = PyscriptsCache(self.message_bus.mbcontext)
            self.loyalty_service = LoyaltyService(
                message_bus=self.message_bus,
                config=self.config,
                logger=self.logger,
            )
            self.order_service = OrderService()
            self.images_service = ImagesService()
            self.payment_service = PaymentService(
                message_bus=self.message_bus,
                config=self.config,
                pos_repository=self.pos_repository,
            )
            self.product_info_service = ProductInfoService(self.message_bus)
            self.fiscal_service.get_electronic_payments_id()

            self.electronic_payment_service = ElectronicPaymentService(
                logger=self.logger,
                message_bus=self.message_bus,
                electronic_payments_id=self.fiscal_service.electronic_payments_id,
            )
        else:
            self.api_service = ApiService(self.config, self.logger)

            events_processors = self._build_events_processors()
            default_message_processor_executor_factory = DefaultMessageProcessorExecutorFactory(self.callbacks)
            self.message_handler = MessageProcessorMessageHandler(events_processors,
                                                                  None,
                                                                  default_message_processor_executor_factory)

    def build_message_handler(self, message=None, event=None):
        # type: (Optional[Message], Optional[Event]) -> MessageHandler

        if self.flask_server:
            processors_routes = self._build_processors_routes()
            http_message_processor = HttpMessageProcessorMessageHandler(route_processor=processors_routes,
                                                                        callbacks=self.callbacks)
            return http_message_processor
        else:
            return self.message_handler

    def destroy_message_handler(self, message_handler):
        # type: (MessageHandler) -> None

        pass

    def destroy_singletons(self):
        # type: () -> None

        pass

    def _build_events_processors(self):
        # type: () -> Optional[Dict[str, MessageProcessor]]

        electronic_payment_event_interactor = ElectronicPaymentEventInteractor(self.api_service)

        electronic_payment_close_dialog_processor = \
            ElectronicPaymentCloseDialogProcessor(electronic_payment_event_interactor)
        electronic_payment_show_qrcode_processor = \
            ElectronicPaymentShowQRCodeProcessor(electronic_payment_event_interactor)
        electronic_payment_show_choices_processor = \
            ElectronicPaymentShowChoicesProcessor(electronic_payment_event_interactor)
        electronic_payment_show_input_processor = \
            ElectronicPaymentShowInputProcessor(electronic_payment_event_interactor)
        electronic_payment_show_message_processor = \
            ElectronicPaymentShowMessageProcessor(electronic_payment_event_interactor)
        electronic_payment_show_question_processor = \
            ElectronicPaymentShowQuestionProcessor(electronic_payment_event_interactor)

        events_processors = {
            ListenedEvents.ELECTRONIC_PAYMENT_CLOSE_DIALOGS: electronic_payment_close_dialog_processor,
            ListenedEvents.ELECTRONIC_PAYMENT_SHOW_QRCODE: electronic_payment_show_qrcode_processor,
            ListenedEvents.ELECTRONIC_PAYMENT_SHOW_CHOICES: electronic_payment_show_choices_processor,
            ListenedEvents.ELECTRONIC_PAYMENT_SHOW_INPUT: electronic_payment_show_input_processor,
            ListenedEvents.ELECTRONIC_PAYMENT_SHOW_MESSAGE: electronic_payment_show_message_processor,
            ListenedEvents.ELECTRONIC_PAYMENT_SHOW_QUESTION: electronic_payment_show_question_processor
        }

        return events_processors

    def _build_memory_cache(
        self,
    ):
        # type: (...) -> Optional[Dict[str, Any[Dict[str, CacheManager], CacheManager]]]

        if not self.flask_server:
            return None

        eft_time = self.config.refresh_cache_time.get("eft", 5)
        fiscal_time = self.config.refresh_cache_time.get("fiscal", 5)
        manager_time = self.config.refresh_cache_time.get("manager", 1)
        menu_time = self.config.refresh_cache_time.get("menu", 5)
        printer_time = self.config.refresh_cache_time.get("printer", 5)

        eft_cache_expiration = PeriodBasedExpiration(period_in_minutes=eft_time)
        fiscal_cache_expiration = PeriodBasedExpiration(period_in_minutes=fiscal_time)
        manager_cache_expiration = PeriodBasedExpiration(period_in_minutes=manager_time)
        menu_cache_expiration = PeriodBasedExpiration(period_in_minutes=menu_time)
        printer_cache_expiration = PeriodBasedExpiration(period_in_minutes=printer_time)

        fiscal_cache = CacheManager(
            cache_expiration=fiscal_cache_expiration,
            threaded=True,
        )
        menu_cache = CacheManager(
            cache_expiration=menu_cache_expiration,
            threaded=True,
        )

        pos_id_list = [str(pos_map.pos_id) for pos_map in self.config.api_key_mapping]

        eft_cache_manager = CacheManager(
            cache_expiration=eft_cache_expiration,
            threaded=True,
        )
        eft_cache = dict([
            (pos_id, eft_cache_manager)
            for pos_id in pos_id_list
        ])

        manager_cache_manager = CacheManager(
            cache_expiration=manager_cache_expiration,
            threaded=True,
        )
        manager_cache = dict([
            (pos_id, manager_cache_manager)
            for pos_id in pos_id_list
        ])

        printer_cache_manager = CacheManager(
            cache_expiration=printer_cache_expiration,
            threaded=True,
        )
        printer_cache = dict([
            (pos_id, printer_cache_manager)
            for pos_id in pos_id_list
        ])

        return dict(
            fiscal=fiscal_cache,
            menu=menu_cache,
            manager=manager_cache,
            printer=printer_cache,
            eft=eft_cache,
        )

    def _build_processors_routes(self):
        # type: () -> Dict[Route, MessageProcessor]

        customization_get_styles_interactor = GetStylesInteractor(
            logger=self.logger,
            config=self.config
        )
        order_add_items_interactor = \
            AddItemsInteractor(self.logger, self.config, self.pos_repository)
        order_cancel_interactor = \
            OrderCancelInteractor(self.logger, self.config, self.pos_repository)
        order_delete_line_interactor = \
            OrderDeleteLineInteractor(self.logger, self.config, self.pos_repository)
        order_close_shopping_cart_interactor = \
            CloseShoppingCartInteractor(self.logger, self.config, self.pos_repository, self.order_service)
        order_create_interactor = \
            OrderCreateInteractor(self.logger, self.config, self.pos_repository)
        order_add_properties_interactor = \
            AddPropertiesInteractor(self.logger, self.config, self.pos_repository)

        order_finalize_interactor = OrderFinalizeInteractor(
            self.logger,
            self.config,
            self.pos_repository,
            self.fiscal_service,
            self.printer_service,
        )

        order_get_detail_interactor = OrderGetDetailInteractor(
            self.logger,
            self.config,
            self.pos_repository,
            self.order_service,
        )

        order_insert_payment_interactor = OrderInsertPaymentInteractor(
            self.logger,
            self.config,
            self.pos_repository,
            self.fiscal_service,
            self.payment_service,
            self.electronic_payment_service,
        )

        order_change_items_quantity_interactor = \
            ChangeItemsQuantityInteractor(self.logger, self.config, self.pos_repository)
        order_reopen_shopping_cart_interactor = ReopenShoppingCartInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            order_service=self.order_service
        )
        order_apply_benefit_interactor = ApplyBenefitInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            order_service=self.order_service,
        )
        order_apply_coupon_interactor = ApplyCouponInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            coupon_service=self.coupon_service,
            order_service=self.order_service
        )
        order_remove_coupon_interactor = RemoveCouponInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            order_service=self.order_service
        )
        order_get_coupon_interactor = GetCouponInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            order_service=self.order_service,
        )
        menu_get_products_interactor = GetProductsInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            cache_menu_products=self.cache_menu_products,
        )
        menu_get_ruptured_products = GetRupturedProducts(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            cache_menu_ruptured_items=self.cache_menu_ruptured_items,
        )
        menu_get_navigation_interactor = GetNavigationInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            cache_navigation=self.cache_menu_navigation
        )
        menu_get_images_interactor = GetImagesInteractor(self.logger, self.config, self.images_service)
        menu_get_banners_interactor = GetBannersInteractor(
            logger=self.logger,
            config=self.config
        )
        menu_get_up_sell_part_codes_interactor = GetUpSellPartCodesInteractor(
            logger=self.logger,
            config=self.config
        )
        menu_get_product_info_interactor = GetProductInfoInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            product_info_service=self.product_info_service
        )
        payment_get_payment_types_interactor = GetPaymentTypesInteractor(
            self.logger,
            self.config,
            self.pos_repository,
            self.payment_service
        )
        peripheral_electronic_payment_read_messages_interactor = \
            ReadMessagesInteractor(
                self.logger,
                self.config,
                self.pos_repository,
                self.fiscal_service,
                self.electronic_messages
            )
        peripheral_electronic_payment_clear_messages_interactor = \
            ClearMessagesInteractor(
                self.logger,
                self.config,
                self.pos_repository,
                self.electronic_messages
            )
        peripheral_electronic_payment_send_responses_interactor = \
            SendResponsesInteractor(
                self.logger,
                self.config,
                self.pos_repository,
                self.fiscal_service,
                self.electronic_messages
            )
        peripheral_print_text_interactor = \
            PrintTextInteractor(self.logger, self.config, self.pos_repository)
        peripheral_read_scanner_interactor = \
            ReadScannerInteractor(self.logger, self.config, self.pos_repository)
        status_get_store_interactor = GetStoreInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            message_bus=self.message_bus,
            memory_cache=self.memory_cache,
        )
        cache_peripheral_electronic_payment_interactor = \
            CacheInteractor(self.logger, self.config, self.electronic_messages)

        customization_get_store_config_interactor = GetStoreConfigInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository
        )

        customization_get_custom_images_interactor = GetCustomImagesInteractor(
            logger=self.logger,
            config=self.config,
        )

        customization_get_text_interactor = GetTextInteractor(
            self.logger,
            self.config,
            self.pos_repository
        )

        order_cancel_payment_interactor = CancelPaymentInteractor(
            self.logger,
            self.config,
            self.pos_repository
        )

        order_save_interactor = OrderSaveInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            printer_service=self.printer_service,
        )

        search_customer_info_interactor = SearchCustomerInfoInteractor(
            logger=self.logger,
            config=self.config,
            pos_repository=self.pos_repository,
            loyalty_service=self.loyalty_service,
        )

        auto_mapped_apply_coupon_message_processor = PosLoggerAutoMappedMessageProcessor(
            request_type=ApplyCouponRequest,
            interactor=order_apply_coupon_interactor,
            exception_map={
                AuthValidationErrors: Responses.AuthValidation,
                ClientCustomError: Responses.ClientCustomError,
                ExternalServiceErrors: Responses.ExternalServicesError,
                InUseError: Responses.InUseError,
                NotAvailableError: Responses.NotAvailableError,
                NotFoundError: Responses.NotFoundError,
                OperationErrors: Responses.OperationErrors,
                ValidationError: Responses.ValidationError,
                BlockedError: Responses.BlockedError,
            },
            success_status=200,
            log_path=self.config.loader_path,
            component_name=self.config.component_name,
            logger=self.logger,
            logger_created=self.logger_created,
        )

        processor_routes = {
            Route("GET", "/order/getDetail/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=OrderGetDetailRequest,
                interactor=order_get_detail_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/create/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=OrderCreateRequest,
                interactor=order_create_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                success_status=201,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/addProperties/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=AddPropertiesRequest,
                interactor=order_add_properties_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                success_status=204,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/addItems/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=AddItemsRequest,
                interactor=order_add_items_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                success_status=204,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/changeItemsQuantity/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=ChangeItemsQuantityRequest,
                interactor=order_change_items_quantity_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                success_status=204,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/insertPayment/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=OrderInsertPaymentRequest,
                interactor=order_insert_payment_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors,
                    BadRequestError: Responses.BadRequestError,
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/registerPayment/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=OrderInsertPaymentRequest,
                interactor=order_insert_payment_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors,
                    BadRequestError: Responses.BadRequestError,
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("DELETE", "/order/cancelPayment/{posId}/{tenderId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=CancelPaymentRequest,
                interactor=order_cancel_payment_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/cancel/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=OrderCancelRequest,
                interactor=order_cancel_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                success_status=204,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("DELETE", "/order/deleteLine/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=OrderDeleteLineRequest,
                interactor=order_delete_line_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                success_status=204,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/closeShoppingCart/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=CloseShoppingCartRequest,
                interactor=order_close_shopping_cart_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/reopenShoppingCart/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=ReopenShoppingCartRequest,
                interactor=order_reopen_shopping_cart_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/finalize/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=OrderFinalizeRequest,
                interactor=order_finalize_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/applyCoupon/{posId}"): auto_mapped_apply_coupon_message_processor,
            Route("POST", "/order/applyCoupon/{posId}/{language}"): auto_mapped_apply_coupon_message_processor,

            Route("DELETE", "/order/removeCoupon/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=RemoveCouponRequest,
                interactor=order_remove_coupon_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),
            Route("POST", "/order/save/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=OrderSaveRequest,
                interactor=order_save_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors,
                    BadRequestError: Responses.BadRequestError,
                },
                success_status=200,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/order/getCoupon/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetCouponRequest,
                interactor=order_get_coupon_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                success_status=200,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/order/applyBenefit/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=ApplyBenefitRequest,
                interactor=order_apply_benefit_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors,
                },
                success_status=200,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/menu/products"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetProductsRequest,
                interactor=menu_get_products_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                response_content_type="application/gzip",
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/menu/rupturedProducts"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetRupturedProductsRequest,
                interactor=menu_get_ruptured_products,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/menu/navigation/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetNavigationRequest,
                interactor=menu_get_navigation_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/menu/productInfo/{language}"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetProductInfoRequest,
                interactor=menu_get_product_info_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/menu/images"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetImagesRequest,
                interactor=menu_get_images_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/menu/banners"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetBannersRequest,
                interactor=menu_get_banners_interactor,
                exception_map={
                    AuthValidationErrors: Responses.AuthValidation
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/menu/upSellPartCodes"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetUpSellPartCodesRequest,
                interactor=menu_get_up_sell_part_codes_interactor,
                exception_map={
                    AuthValidationErrors: Responses.AuthValidation
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/payment/paymentTypes"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetPaymentTypesRequest,
                interactor=payment_get_payment_types_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/peripheral/electronicPayment/readMessages/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=ReadMessagesRequest,
                interactor=peripheral_electronic_payment_read_messages_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/peripheral/electronicPayment/clearMessages/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=ClearMessagesRequest,
                interactor=peripheral_electronic_payment_clear_messages_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/peripheral/electronicPayment/sendResponse/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=SendResponsesRequest,
                interactor=peripheral_electronic_payment_send_responses_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                success_status=204,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/peripheral/printText/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=PrintTextRequest,
                interactor=peripheral_print_text_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError
                },
                success_status=204,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/peripheral/readScanner/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=ReadScannerRequest,
                interactor=peripheral_read_scanner_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                success_status=200,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/status/store/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetStoreRequest,
                interactor=status_get_store_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("POST", "/cache/peripheral/electronicPayment"): PosLoggerAutoMappedMessageProcessor(
                request_type=CacheRequest,
                interactor=cache_peripheral_electronic_payment_interactor,
                exception_map={},
                success_status=204,
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/customization/getStyles"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetStylesRequest,
                interactor=customization_get_styles_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/customization/getText"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetTextRequest,
                interactor=customization_get_text_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/customization/storeConfig/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetStoreConfigRequest,
                interactor=customization_get_store_config_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/customization/getCustomImages"): PosLoggerAutoMappedMessageProcessor(
                request_type=GetCustomImagesRequest,
                interactor=customization_get_custom_images_interactor,
                exception_map={
                    AuthValidationErrors: Responses.AuthValidation,
                    OperationErrors: Responses.OperationErrors,
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),

            Route("GET", "/loyalty/getCustomer/{posId}"): PosLoggerAutoMappedMessageProcessor(
                request_type=SearchCustomerInfoRequest,
                interactor=search_customer_info_interactor,
                exception_map={
                    ValidationError: Responses.ValidationError,
                    AuthValidationErrors: Responses.AuthValidation,
                    ExternalServiceErrors: Responses.ExternalServicesError,
                    OperationErrors: Responses.OperationErrors,
                    NotFoundError: Responses.NotFoundError,
                },
                log_path=self.config.loader_path,
                component_name=self.config.component_name,
                logger=self.logger,
                logger_created=self.logger_created,
            ),
        }

        return processor_routes
