from typing import Dict, Tuple, Type, Union

from edpdependencyinjection import DependencyContext
from httpmessageprocessor import RouterProcessorBuilder, RouteNotMapped
from messageprocessor import MessageProcessor
from simplehttprouter import FoundRoute, Route, SimpleHttpRouter

AcceptableRoutesImplementations = Union[Type[MessageProcessor], MessageProcessor]

class DiRouterProcessorBuilder(RouterProcessorBuilder):
    def __init__(
        self,
        dependency_context: DependencyContext,
        route_definition: Dict[Route, AcceptableRoutesImplementations],
    ):
        self.dependency_context = dependency_context
        self.route_definition = route_definition

        self.router = SimpleHttpRouter(list(self.route_definition.keys()))
        self.dependency_context.add_dependency_instance(self)


    def get_processor(self, route: Route) -> Tuple[FoundRoute, MessageProcessor]:
        found_route = self.router.get_route(route)
        if found_route is None:
            raise RouteNotMapped(route.method, route.path)

        processor = self.route_definition[found_route.route]
        if isinstance(processor, MessageProcessor):
            return found_route, processor
        else:
            processor_instance = self.dependency_context.get_instance(processor)
            return found_route, processor_instance
