from typing import Dict, Optional

from messageprocessor import MessageProcessor
from simplehttprouter import Route

from ..builder import OpenApiModelBuilder
from ..builder.dto import BuilderConfig
from ..builder.impl import OpenApiModelBuilderImpl
from ..builder.registry import get_descriptors
from ..interactor.dto import AutoOpenApiYamlBuilderRequest
from ..model import ServerModel


class AutoOpenApiYamlBuilderInteractor:
    def __init__(
        self,
        routes: Optional[Dict[Route, MessageProcessor]] = None,
        builder: Optional[OpenApiModelBuilder] = None,
        config: Optional[BuilderConfig] = None,
    ):
        self.routes = routes
        self.builder = builder
        self._config = config

    def get_builder(self):
        if self.builder is None:
            resolved: BuilderConfig = {**(self._config or {})}
            resolved.setdefault("descriptors", get_descriptors())
            self.builder = OpenApiModelBuilderImpl(config=resolved)
        return self.builder

    def execute(self, request: AutoOpenApiYamlBuilderRequest) -> str:
        builder = self.get_builder()
        if request.host is not None:
            model = builder.get_model()
            if not any(s.url == request.host for s in (model.servers or [])):
                model.add_server(server=ServerModel(url=request.host))

        if self.routes is not None:
            for route, processor in self.routes.items():
                builder.add_processor_path(
                    route=route,
                    processor=processor,
                )

        return builder.build_open_api_yaml()