import hmac
import random
import time

from django.conf import settings
from django.contrib.auth import get_user_model
from django.db.models import Sum
from django.shortcuts import redirect, render

from common.middleware import gate_whitelist
from library.models import Project, Version


def _under_lockout(request):
    lock_until = request.session.get('lock_until')
    if lock_until and time.time() < lock_until:
        return True
    return False


def _start_lockout(request):
    duration = random.randint(30, 300)
    request.session['lock_until'] = time.time() + duration


@gate_whitelist
def gate(request):
    if request.method == 'POST':
        if _under_lockout(request):
            return render(request, 'landing/gate.html', {
                'error': 'Incorrect password.',
            })

        submitted = request.POST.get('password', '')
        master = settings.PASSWORD or ''
        if hmac.compare_digest(submitted, master):
            request.session['authorized'] = True
            request.session.pop('lock_until', None)
            return redirect('landing:home')
        else:
            _start_lockout(request)
            return render(request, 'landing/gate.html', {
                'error': 'Incorrect password.',
            })

    if request.session.get('authorized'):
        return redirect('landing:home')

    return render(request, 'landing/gate.html')


def home(request):
    latest_projects = (
        Project.objects.select_related('owner', 'thumbnail')
        .prefetch_related('tag_links__tag__category', 'versions')
        .order_by('-created_at')[:4]
    )
    total_downloads = Version.objects.aggregate(total=Sum('downloads'))['total'] or 0
    creators = (
        get_user_model().objects.filter(projects__isnull=False).distinct().count()
    )
    context = {
        'latest_projects': latest_projects,
        'stats': {
            'creators': creators,
            'packs': Project.objects.count(),
            'downloads': total_downloads,
            'versions': Version.objects.count(),
        },
    }
    return render(request, 'landing/home.html', context)