import logging
import xml.sax

from cache_functions import UsersInfoCache
from xml.etree import cElementTree as eTree

from messageprocessorutil import UuidMessageProcessor
from mwrepository import ProductRepository
from production.manager import ProductionManager
from production.model import ProductionOrder

from ._SystemOrderParser import SystemOrderParser

performance_event_logger = logging.getLogger("ProductionPerformanceEvent")


class OrderModifiedProcessor(UuidMessageProcessor):
    def __init__(self, production_manager, product_repository, user_cache_thread=None):
        # type: (ProductionManager, ProductRepository, UsersInfoCache) -> None
        super(OrderModifiedProcessor, self).__init__()
        self.production_manager = production_manager
        self.part_code_jit_lines = product_repository.get_all_part_code_jit_lines()
        self.user_cache_thread = user_cache_thread

    def parse_data(self, data):
        self._performance_log(data)
        handler = SystemOrderParser(self.part_code_jit_lines, user_cache_thread=self.user_cache_thread)
        xml.sax.parseString(data, handler)
        if handler.order.order_id == 0:
            return None
        return handler.order

    @staticmethod
    def _performance_log(
        data,   # type: str
    ):
        # type (...) -> None

        try:
            data_xml = eTree.XML(data)
            order_id = (data_xml.find(".//Order") or {}).get("orderId", "")
            subject = data_xml.get("subject", "")
            event_type = data_xml.get("type", "")
            message = "Event - {:10} / {:20} / {}".format(order_id, subject, event_type)
            performance_event_logger.info(message)
        except Exception as _:
            performance_event_logger.exception("Error parsing event xml")

    def call_business(self, order):
        # type: (ProductionOrder) -> None
        if order is not None:
            self.production_manager.order_modified(order)

    def format_response(self, message_bus, message, event, input_obj, result):
        # no response
        pass

    def format_exception(self, message_bus, message, event, input_obj, exception):
        # no response
        pass

    def format_parse_exception(self, message_bus, message, event, data, exception):
        # no response
        pass
