# -*- coding: utf-8 -*-
import time

from fastapi import FastAPI, Request
from intranet.forms.micro.core.src.types import AppTypes
from intranet.forms.micro.core.src.user import get_yauser
from intranet.forms.micro.core.src.db import get_pool

from .conf import settings
from .views import router


def get_app_type(request: Request, default: AppTypes) -> AppTypes:
    app_type = None
    if 'headers' in request.scope:
        headers = dict(request.scope['headers'])
        app_type_buf = headers.get(b'x-apptype')
        if app_type_buf:
            app_type = getattr(AppTypes, app_type_buf.decode(), None)
    return app_type or default


async def process_apptype(request: Request, call_next):
    app_type = get_app_type(request, settings.default_app_type)
    request.scope['app_type'] = app_type
    request.scope['settings'] = settings.get_settings(app_type)
    response = await call_next(request)
    return response


async def process_yauser(request: Request, call_next):
    assert 'settings' in request.scope
    yauser = await get_yauser(request)
    request.scope['yauser'] = yauser
    response = await call_next(request)
    return response


async def process_execution_time(request: Request, call_next):
    start_time = time.monotonic_ns()
    response = await call_next(request)
    process_time = int((time.monotonic_ns() - start_time) / 1000000)
    response.headers['X-Process-Time'] = str(process_time)
    return response


async def shutdown_pool_connections():
    for app_type in AppTypes:
        pool = get_pool(app_type)
        await pool.close()


app = FastAPI()
app.include_router(router, prefix='/v1', tags=[settings.app_name])
app.middleware('http')(process_execution_time)
app.middleware('http')(process_yauser)
app.middleware('http')(process_apptype)
app.on_event('shutdown')(shutdown_pool_connections)
