import json

from typing import Any

from application.interactor import UserUpdaterInteractor
from application.model import AsyncUuidMessageProcessor
from application.model.customexception import SomeUserLogged
from messagebus import DefaultToken, DataType, Message
from application.util import settings


class UserUpdaterProcessor(AsyncUuidMessageProcessor):
    def __init__(self, interactor):
        # type: (UserUpdaterInteractor) -> None

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

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

        logged_users = json.loads(data)
        return logged_users

    def call_business(self, logged_users):
        # type: (Any) -> Any

        settings.clear_status()
        return self.interactor.update_users(logged_users)

    def format_response(self, message_bus, message, event, _, response):
        token = DefaultToken.TK_SYS_ACK
        if response is not None and "users_disable_logged" in response:
            token = DefaultToken.TK_SYS_NAK
            response = str(response)

        reply_message = Message(token, DataType.param, response)
        if message:
            message_bus.reply_message(message, reply_message)
        elif event:
            message_bus.reply_event(event, reply_message)

    def format_exception(self, message_bus, message, event, _, exception):
        self._reply_exception(event, exception, message, message_bus)

    def format_parse_exception(self, message_bus, message, event, _, exception):
        self._reply_exception(event, exception, message, message_bus)

    @staticmethod
    def _reply_exception(event, exception, message, message_bus):
        reply_message = Message(DefaultToken.TK_SYS_NAK, DataType.param, str(exception))
        if message:
            data = str(type(exception).__name__)
            if isinstance(exception, SomeUserLogged):
                data = str(type(exception).__name__) + "|" + exception.message

            reply_message = Message(DefaultToken.TK_SYS_NAK, DataType.param, data)
            message_bus.reply_message(message, reply_message)
        elif event:
            message_bus.reply_event(event, reply_message)
