from hashlib import md5
from time import time

from django.contrib import auth as dj_auth
from django.contrib import messages
from django.utils.translation import pgettext

from ..conf import settings

TOKEN_KEY = "misago_admin_session_token"
UPDATED_KEY = "misago_admin_session_updated"


# Admin session state controls
def is_admin_authorized(request):
    if request.user.is_anonymous:
        return False

    if not request.user.is_staff:
        return False

    admin_token = request.session.get(TOKEN_KEY)
    if not admin_token == make_user_admin_token(request.user):
        return False

    updated = request.session.get(UPDATED_KEY, 0)
    if updated < time() - (settings.MISAGO_ADMIN_SESSION_EXPIRATION * 60):
        if updated:
            request.session.pop(UPDATED_KEY, None)
            messages.info(
                request, pgettext("admin auth", "Your admin session has expired.")
            )
        return False

    return True


def authorize_admin(request):
    request.session[TOKEN_KEY] = make_user_admin_token(request.user)
    request.session[UPDATED_KEY] = int(time())


def update_admin_authorization(request):
    request.session[UPDATED_KEY] = int(time())


def remove_admin_authorization(request):
    request.session.pop(TOKEN_KEY, None)
    request.session.pop(UPDATED_KEY, None)


def make_user_admin_token(user):
    formula = (str(user.pk), user.email, user.password, settings.SECRET_KEY)
    return md5(":".join(formula).encode()).hexdigest()


# Login/logout exposed
login = dj_auth.login
logout = dj_auth.logout


# Register signal for logout to make sure eventual admin session is closed
def django_login_handler(sender, **kwargs):
    request, user = kwargs["request"], kwargs["user"]
    try:
        admin_namespace = request.admin_namespace
    except AttributeError:
        admin_namespace = False
    if admin_namespace and user.is_staff:
        authorize_admin(request)


dj_auth.signals.user_logged_in.connect(django_login_handler)


def django_logout_handler(sender, **kwargs):
    remove_admin_authorization(kwargs["request"])


dj_auth.signals.user_logged_out.connect(django_logout_handler)
