# @author Simone Nicol <en0mia.dev@gmail.com>
# @created 22/07/23
from typing import Self

from flask import Request, Response

from easy_route.controllers.abstract_controller import AbstractController
from easy_route.middlewares.abstract_middleware import AbstractMiddleware


class Route(object):
    """This class represents a Route object, with its middlewares and its controller."""
    def __init__(self, request: Request, controller: AbstractController):
        self.request = request
        self.controller = controller
        self.middlewares = []

    def add_middleware(self, middleware: AbstractMiddleware) -> Self:
        """Adds a middleware to the middlewares stack.
        :param middleware: The Middleware to add to the stack.
        :return: Self.
        """
        self.middlewares += [middleware]
        return self

    def add_middlewares(self, middlewares: list[AbstractMiddleware]) -> Self:
        """Adds a list of middlewares to the middlewares stack.
        :param middlewares: The Middlewares to add to the stack.
        :return: Self.
        """
        self.middlewares += middlewares
        return self

    def dispatch(self) -> Response:
        """Executes the Route, validate all the middlewares and then returns the Response
        generated by the Controller.
        If one of the middleware fails (aka returns a Response object), then the flow is stopped
        and the Response generated by the middleware is returned.
        :return:
        """
        for middleware in self.middlewares:
            result = middleware.dispatch(self.request)
            if result:
                return result
        return self.controller.execute(self.request)
