import base64
import logging
import zlib

from abc import ABCMeta
from boto3 import client as BotoClient

from messageprocessorutil import UuidMessageProcessor


logger = logging.getLogger("TopicClient")


class ServerEventProcessor(UuidMessageProcessor):
    __metaclass__ = ABCMeta

    def __init__(
        self,
        event_name,                 # type: str
        store_code,                 # type: str
        context,                    # type: str
        sns_client,                 # type: BotoClient
        sqs_client,                 # type: BotoClient
        topic_arn,                  # type: str
        server_queue_url,           # type: str
        message_maximum_length,     # type: int
    ):
        # type: (...) -> None

        super(ServerEventProcessor, self).__init__(event_name)
        self.store_code = store_code
        self.context = context
        self.sns_client = sns_client
        self.sqs_client = sqs_client
        self.topic_arn = topic_arn
        self.server_queue_url = server_queue_url
        self.message_maximum_length = message_maximum_length

    def parse_data(self, data, event_data):
        return data

    def call_business(self, obj):
        return obj

    def format_response(self, message_bus, message, event, data, result):
        subject = event.subject
        data_length = len(data.encode('utf-8'))
        data_type = "TEXT"
        if data_length > self.message_maximum_length * 1024:
            data_type = "ZIP"
            data = base64.b64encode(zlib.compress(data))

        message_attributes = {
            "Subject": {
                "DataType": "String",
                "StringValue": subject
            },
            "MessageType": {
                "DataType": "String",
                "StringValue": data_type
            },
            "FromStore": {
                "DataType": "String",
                "StringValue": self.store_code
            }
        }
        if self.context is not None:
            message_attributes["Context"] = {
                "DataType": "String",
                "StringValue": self.context
            }

        if self.server_queue_url is not None:
            response = self.sqs_client.send_message(
                QueueUrl=self.server_queue_url,
                MessageBody=data.decode("utf-8"),
                MessageAttributes=message_attributes,
            )
        else:
            response = self.sns_client.publish(
                TopicArn=self.topic_arn,
                Message=data,
                Subject=event.subject,
                MessageAttributes=message_attributes
            )

        if "MessageId" not in response or response["MessageId"] is None or response["MessageId"] == "":
            logger.info("MessageId not found on the response")

    def format_exception(self, message_bus, message, event, input_obj, exception):
        return

    def format_parse_exception(self, message_bus, message, event, data, exception):
        return
