import time
from django.conf import settings
from django.http import HttpResponsePermanentRedirect
from django.utils import timezone


class CanonicalHostMiddleware:
    """
    301-redirect www.thereversetimes.com/... to thereversetimes.com/...

    Both addresses used to serve the same pages, which splits ranking signals
    between two "sites" and weakens brand searches.
    """

    def __init__(self, get_response):
        self.get_response = get_response
        self.canonical = getattr(settings, 'CANONICAL_HOST', '')
        self.scheme = getattr(settings, 'SITE_URL', 'https://').split('://')[0]

    def __call__(self, request):
        host = request.get_host().split(':')[0].lower()
        if self.canonical and host == 'www.' + self.canonical:
            return HttpResponsePermanentRedirect(
                f'{self.scheme}://{self.canonical}{request.get_full_path()}')
        return self.get_response(request)


class AdminLoginThrottleMiddleware:
    """Slow down password guessing on /admin/login/: after 8 wrong tries from one
    address, that address must wait 15 minutes."""
    MAX_FAILURES = 8
    WINDOW = 15 * 60

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

    @staticmethod
    def _ip(request):
        fwd = request.META.get('HTTP_X_FORWARDED_FOR')
        return (fwd.split(',')[0].strip() if fwd else request.META.get('REMOTE_ADDR')) or 'unknown'

    def __call__(self, request):
        if request.method != 'POST' or not request.path.startswith('/admin/login'):
            return self.get_response(request)
        from django.core.cache import cache
        from django.http import HttpResponse
        key = f'admin-login-fail:{self._ip(request)}'
        if cache.get(key, 0) >= self.MAX_FAILURES:
            return HttpResponse('Too many wrong sign-in attempts. Please wait 15 minutes and try again.',
                                status=429, content_type='text/plain; charset=utf-8')
        response = self.get_response(request)
        if response.status_code == 200:  # the form came back = wrong password
            cache.set(key, cache.get(key, 0) + 1, self.WINDOW)
        elif response.status_code in (301, 302):
            cache.delete(key)
        return response
