import json

from messagebus import (
    AckMessage,
    Event,
    Message,
    MessageBus,
    NakMessage,
)
from paymentrouter import PaymentRouter
from typing import Any, Optional
from util import Cache

from ._CommonProcessor import _CommonProcessor


class CacheProcessor(_CommonProcessor):
    def __init__(
        self,
        payment_router,     # type: PaymentRouter
        cache,              # type: Cache
    ):
        # type: (...) -> None

        super(CacheProcessor, self).__init__(payment_router)

        self.cache = cache

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

        return data

    def call_business(
        self,
        data,   # type: str
    ):
        # type: (...) -> Optional[str]

        data = json.loads(data)

        eft_processor = data.get("eftProcessor")
        receipt_data = data.get("receiptData", None)

        if receipt_data is not None:
            self.cache.set_last_receipt(
                receipt_data=receipt_data,
                eft_processor=eft_processor,
            )
            return None

        return self.payment_router.get_last_receipt(eft_processor=eft_processor)

    def format_response(
        self,
        message_bus,    # type: MessageBus
        message,        # type: Message
        event,          # type: Event
        input_obj,      # type: Any
        result,         # type: Any
    ):
        # type: (...) -> None

        message_bus.reply_message(
            message=message,
            reply_message=AckMessage(data=result),
        )

    def format_exception(
        self,
        message_bus,    # type: MessageBus
        message,        # type: Message
        event,          # type: Event
        input_obj,      # type: Any
        exception,      # type: Exception
    ):
        # type: (...) -> None

        self.payment_router._logger.exception("exception: {}".format(exception))
        message_bus.reply_message(
            message=message,
            reply_message=NakMessage(data=exception.message),
        )
