import re
from ipaddress import ip_address

from django.conf import settings
from django.urls import reverse
from django.http import HttpResponseRedirect

EXEMPT_URLS = [
    re.compile(r'^account/*'),
    re.compile(r'^agenda/rendez-vous*'),
    re.compile(r'^login/$'),
    re.compile(r'^logout/$'),
    re.compile(r'^jsi18n/$'),
    re.compile(r'^favicon.ico$'),
]


class LoginRequiredMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        path = request.path_info.lstrip('/')
        ip = ip_address(request.META.get('REMOTE_ADDR'))
        # is_verified checks 2FA auth
        if not request.user.is_verified() and not any(m.match(path) for m in EXEMPT_URLS):
            ip_exempted = any(ip in net for net in settings.EXEMPT_2FA_NETWORKS)
            if request.user.is_authenticated:
                if ip_exempted or request.user.username in settings.EXEMPT_2FA_USERS:
                    return self.get_response(request)
                return HttpResponseRedirect(reverse('two_factor:setup'))
            else:
                login_view = reverse('login') if ip_exempted else reverse('two_factor:login')
                return HttpResponseRedirect("{}?next={}".format(login_view, request.path))
        return self.get_response(request)
