<reponame>sha31dev/pyws
from fastapi import FastAPI, Request, Response
from fastapi.openapi.utils import get_openapi
from gunicorn.app.base import BaseApplication
from starlette.middleware.base import BaseHTTPMiddleware
from typing import List
from pyws.src.api_doc import ApiDoc
from pyws.src.controller import Controller
from pyws.src.config import Config


class Server(BaseApplication):
    def __init__(
        self,
        config: Config = Config(),
        controllers: List[Controller] = [],
        middlewares: List[BaseHTTPMiddleware] = [],
        api_doc: ApiDoc = ApiDoc()
    ):
        self.application = FastAPI()
        self.options = config.to_dict()
        self.controllers = controllers
        self.middlewares = middlewares
        self.__api_doc = api_doc

        self.__routes = []
        super().__init__()

        for controller in self.controllers:
            for middleware in self.middlewares:
                controller.app.add_middleware(middleware)

            self.application.mount('/', controller.app)
            self.__routes.extend(controller.app.routes)

        self.application.openapi = lambda: get_openapi(
            routes=self.__routes,
            **self.__api_doc.to_dict()
        )

    def load_config(self):
        config = {
            key: value for key, value in self.options.items() if key in self.cfg.settings and value is not None
        }

        for key, value in config.items():
            self.cfg.set(key.lower(), value)

    def load(self):
        return self.application
