import re
from typing import List, Callable, Optional

from .logdata import Request


def no_star(request: Request) -> bool:
    return request.url != "*"


def no_plus_http(request: Request) -> bool:
    return "+http" not in request.user_agent


def make_filters(
        regexes: List[str],
        excluded: List[str],
        allowed_codes: Optional[List[int]] = None
) -> List[Callable[[Request], bool]]:

    compiled_patterns = [re.compile(r) for r in regexes]
    target_codes = set(allowed_codes) if allowed_codes else {200, 304}
    excluded_ip_set = set(excluded)

    def filter_url(request):
        for pattern in compiled_patterns:
            if pattern.search(request.url):
                return True
        return False

    def only_successful(request: Request) -> bool:
        return request.response_code in target_codes

    def not_excluded_ip(request):
        return request.ip_address not in excluded_ip_set

    return [
        filter_url,
        only_successful,
        no_star,
        no_plus_http,
        not_excluded_ip,
    ]
