from messagebus import DataType
from typing import (
    Any,
    Optional,
    Union,
)
from xml.etree import cElementTree as eTree

from msgbus import (
    TK_PRN_PRINT,
    MBTimeout,
)
from msgbus import (
    TK_SYS_NAK,
    MBException,
)
from .. import mb_context

from model.customexception import (
    ErrorGettingDevice,
    PrinterError,
)
from utilfunctions import (
    get_sector_name,
    get_device_service,
    get_device_service_error_message,
)
from sysactions import get_model


def send_json_data_print(
    pos_id,         # type: str
    print_data,     # type: str
    model=None,     # type: Optional[eTree.Element]
    order=None,     # type: Optional[eTree.Element]
):
    # type: (...) -> None

    try:
        current_printer = _get_printer(
            pos_id=pos_id,
            order=order,
        )
        msg = mb_context.MB_EasySendMessage(
            dest_name=current_printer,
            token=TK_PRN_PRINT,
            format=DataType.json,
            data=print_data,
            timeout=30 * 1000000,
        )
        if msg.token == TK_SYS_NAK:
            raise PrinterError(msg.data)

    except ErrorGettingDevice as ex:
        if model is None:
            model = get_model(posid=pos_id)

        message = get_device_service_error_message(
            model=model,
            exception=ex,
        )
        raise PrinterError(message)
    except (MBException, MBTimeout) as ex:
        raise PrinterError(ex)


def _get_printer(
    pos_id,         # type: Any[Union[str, int]]
    order=None,     # type: Optional[eTree.Element]
):
    # type: (...) -> str

    sector_name = get_sector_name(order=order) if order else None
    current_printer = get_device_service(
        pos_id=pos_id,
        device_type="printer",
        sector=sector_name,
    )
    return current_printer
