import json

from application.interactor.burn_voucher import BurnVoucherInteractor
from application.interactor.burn_voucher.dto import BurnVoucherRequest

from application.model import AsyncUuidMessageProcessor
from messagebus import (
    DefaultToken,
    DataType,
    Message,
    InternalErrorMessage,
)


class BurnVoucherProcessor(AsyncUuidMessageProcessor):
    def __init__(
        self,           # type: BurnVoucherProcessor
        interactor,     # type: BurnVoucherInteractor
    ):
        # type: (...) -> None

        super(BurnVoucherProcessor, self).__init__()
        self.interactor = interactor

    def parse_data(
        self,           # type: BurnVoucherProcessor
        data,           # type: str
        event_type,     # type: str
    ):
        # type: (...) -> BurnVoucherRequest

        request_json = json.loads(data.decode("utf-8"))
        return BurnVoucherRequest(
            benefit_id=request_json["benefitId"],
            order_picture=request_json["orderPicture"],
            table_picture=request_json.get("tablePicture")
        )

    def call_business(
        self,       # type: BurnVoucherProcessor
        request,    # type: BurnVoucherRequest
    ):
        # type: (...) -> None

        self.interactor.burn_benefit(request=request)

    def format_response(self, message_bus, message, event, request, response):
        message_bus.reply_message(
            message=message,
            reply_message=Message(
                token=DefaultToken.TK_SYS_ACK,
                data_type=DataType.string,
            ),
        )

    def format_exception(self, message_bus, message, event, input_obj, exception):
        message_bus.reply_message(
            message=message,
            reply_message=InternalErrorMessage(ex=exception)
        )

    def format_parse_exception(self, message_bus, message, event, data, exception):
        self.format_exception(
            message_bus=message_bus,
            message=message,
            event=event,
            input_obj=data,
            exception=exception
        )
