from logging import Logger
from typing import Dict

from messagebus import MessageBus

from production.manager import ProductionManager
from production.model import PrinterNameFoundException
from production.treebuilder import ViewConfiguration
from production.view import (
    PrinterView,
    PicklistPrinterView,
    ReportsPrinterView,
)
from production.view.printerviewservices.reportgenerator import PickListReportGenerator
from production.view.printerviewservices.reportprinter import PickListPrinter

from ._CommonViewBuilder import (
    get_extra,
    get_logger,
)


class PrinterViewBuilder(object):
    def __init__(
        self,                           # type: PrinterViewBuilder
        message_bus,                    # type: MessageBus
        loggers,                        # type: Dict[str, Logger]
        production_manager,             # type: ProductionManager
        timeout_to_cleanup_devices,     # type: int
    ):
        # type: (...) -> None

        self.production_manager = production_manager
        self.message_bus = message_bus
        self.loggers = loggers
        self.timeout_to_cleanup_devices = timeout_to_cleanup_devices

    def build(self, config):
        # type: (ViewConfiguration) -> PrinterView

        logger = get_logger(config, self.loggers)

        if "PrinterName" not in config.extra_config:
            raise PrinterNameFoundException("PrinterView without printer: {}".format(config.name))

        if config.extra_config.get("ReportType") == "nreports":
            return ReportsPrinterView(
                name=config.name,
                report_name=config.extra_config["ReportName"],
                printer_name=config.extra_config["PrinterName"],
                pick_list_name=config.extra_config.get("PickListName", ""),
                production_manager=self.production_manager,
                timeout=int(get_extra(config, "Timeout", 10000)) * 1000,
                message_bus=self.message_bus,
                tags_on_print=get_extra(config, "TagOnPrint", "printed").split(";"),
                logger=logger,
            )

        return self.build_picklist_printer_view(
            config=config,
            logger=logger,
        )

    def build_picklist_printer_view(
        self,       # type: PrinterViewBuilder
        config,     # type: ViewConfiguration
        logger,     # type: Logger
    ):
        # type: (...) -> PicklistPrinterView

        picklist_report_generator = PickListReportGenerator(
            message_bus=self.message_bus,
            configuration_json_path=config.extra_config.get("ConfigurationJsonPath", "").encode("utf-8"),
            picklist_name=config.extra_config.get("PickListName", "").encode("utf-8"),
            logger=logger
        )

        picklist_printer = PickListPrinter(
            message_bus=self.message_bus,
            timeout=int(get_extra(config, "Timeout", 10000)) * 1000,
            name=config.name,
            logger=logger,
            kds_id=str(config.extra_config.get("KdsId", "").replace("KDS", "") or ""),
            printer=config.extra_config["PrinterName"].encode("utf-8"),
            timeout_to_cleanup_devices=self.timeout_to_cleanup_devices,
        )

        return PicklistPrinterView(
            name=config.name,
            production_manager=self.production_manager,
            report_generator=picklist_report_generator,
            picklist_printer=picklist_printer,
            tags_on_print=get_extra(config, "TagOnPrint", "printed").split(";"),
            logger=get_logger(config, self.loggers),
        )
