import logging
from typing import List, Optional

import boto3

from messagehandler import MessageHandlerBuilder
from messageprocessor import (
    MessageProcessorMessageHandler,
    DefaultMessageProcessorExecutorFactory,
)
from topicclient.processor import ServerEventProcessor

from messageprocessorutil import LoggingProcessorCallback

logger = logging.getLogger("TopicClient")


class TopicClientMessageHandlerBuilder(MessageHandlerBuilder):
    def __init__(
        self,
        topic_arn,                  # type: str
        server_queue_url,           # type: Optional[str]
        endpoint_url,               # type: str
        region_name,                # type: str
        aws_access_key_id,          # type: str
        aws_secret_access_key,      # type: str
        subjects,                   # type: List[str]
        store_code,                 # type: str
        context,                    # type: str
        message_maximum_length,     # type: int
    ):
        # type: (...) -> None

        self.topic_arn = topic_arn
        self.server_queue_url = server_queue_url
        self.endpoint_url = endpoint_url
        self.region_name = region_name
        self.aws_access_key_id = aws_access_key_id
        self.aws_secret_access_key = aws_secret_access_key
        self.subjects = subjects
        self.store_code = store_code
        self.context = context
        self.message_maximum_length = message_maximum_length

        self.message_handler = None

    def build_singletons(self):
        sqs_client = boto3.client(
            "sqs",
            aws_access_key_id=self.aws_access_key_id,
            aws_secret_access_key=self.aws_secret_access_key,
            region_name=self.region_name,
            endpoint_url=self.endpoint_url
        )

        sns_client = boto3.client(
            "sns",
            aws_access_key_id=self.aws_access_key_id,
            aws_secret_access_key=self.aws_secret_access_key,
            region_name=self.region_name,
            endpoint_url=self.endpoint_url
        )

        event_processors = {}
        for subject in self.subjects:
            server_event_processor = ServerEventProcessor(
                event_name=subject,
                store_code=self.store_code,
                context=self.context,
                sns_client=sns_client,
                sqs_client=sqs_client,
                topic_arn=self.topic_arn,
                server_queue_url=self.server_queue_url,
                message_maximum_length=self.message_maximum_length,
            )
            event_processors[subject] = server_event_processor

        callbacks = [LoggingProcessorCallback(logger)]
        self.message_handler = MessageProcessorMessageHandler(
            event_processors=event_processors,
            message_processors=None,
            executor_factory=DefaultMessageProcessorExecutorFactory(callbacks),
        )

    def build_message_handler(self, message, event):
        return self.message_handler

    def destroy_message_handler(self, message_handler):
        return

    def destroy_singletons(self):
        return
