from typing import Optional

from httpmessageprocessor import HttpMessageProcessor
from httpmessageprocessor._SimpleHttpRouterRouterProcessorBuilder import SimpleHttpRouterRouterProcessorBuilder
from messagebus import Event, Message, DefaultToken
from messagehandler import MessageHandlerBuilder
from messageprocessor import MessageProcessorMessageHandler, MessageProcessor

from edpopenapibuilder.builder import OpenApiModelBuilder
from edpopenapibuilder.builder.dto import build_params
from edpopenapibuilder.builder.registry import get_builder


def build_from_message_handler_builder(
    message_handler_builder: MessageHandlerBuilder,
    message: Optional[Message] = None,
    event: Optional[Event] = None,
) -> OpenApiModelBuilder:
    model_builder = get_builder()

    handler = message_handler_builder.build_message_handler(
        message=message,
        event=event
    )

    if isinstance(handler, MessageProcessorMessageHandler):
        processor: MessageProcessor = handler.message_processors.get(DefaultToken.TK_HTTP_MSG)
        if isinstance(processor, HttpMessageProcessor):
            route_processor_builder = processor.route_processor_builder
            if isinstance(route_processor_builder, SimpleHttpRouterRouterProcessorBuilder):
                route_processor = route_processor_builder.route_processor
                for route, processor in route_processor.items():
                    model_builder.add_processor_path(
                        route=route,
                        processor=processor,
                    )

            try:
                from dihttpmessageprocessor import AutoMappedDiRouterProcessorBuilder

                if isinstance(route_processor_builder, AutoMappedDiRouterProcessorBuilder):
                    for route, definition in route_processor_builder.auto_mapped_definition.items():
                        model_builder.add_interactor_path(
                            route_params=build_params(
                                route=route,
                                interactor_type=definition.interactor_type,
                                request_type=definition.request_type,
                                processor_type=definition.processor_type,
                                response_content_type=definition.response_content_type,
                                success_status=definition.success_status
                            )
                        )

                    for route, processor_type in route_processor_builder.route_definition.items():
                        model_builder.add_processor_path(route=route, processor=processor_type)
            except ImportError:
                ...

    return model_builder


def build_yaml_from_message_handler_builder(
    message_handler_builder: MessageHandlerBuilder,
    message: Optional[Message] = None,
    event: Optional[Event] = None,
) -> str:
    model_builder = build_from_message_handler_builder(
        message_handler_builder=message_handler_builder,
        message=message,
        event=event,
    )
    return model_builder.build_open_api_yaml()
