# coding:utf-8
import fnmatch
import typing as t
from functools import cached_property

from makit.web import status
from makit.web.context import Context
from makit.web.middleware import Middleware


class HostMiddleware(Middleware):

    def __init__(
            self,
            allowed_hosts: t.List[str] | None = None,
            disallowed_hosts: t.List[str] | None = None,
    ):
        self.allowed_hosts = allowed_hosts or ['*']
        self.disallowed_hosts = disallowed_hosts or []

    @cached_property
    def allow_all(self):
        return '*' in self.allowed_hosts

    async def __call__(self, c: Context):
        host = c.headers.get("host").split(":")[0]
        allowed = True
        for pattern in self.disallowed_hosts:
            if fnmatch.fnmatch(host, pattern):
                allowed = False
                break

        if not allowed:
            await c.respond_text('disallowed host!', status_code=status.HTTP_403_FORBIDDEN)
            return

        allowed = self.allow_all
        for pattern in self.allowed_hosts:
            if fnmatch.fnmatch(host, pattern):
                allowed = True
                break

        if allowed:
            await c.next()
        else:
            await c.respond_text('disallowed host!', status_code=status.HTTP_403_FORBIDDEN)
