from flask import request, flash, make_response, redirect, url_for, abort
from flask_login import current_user, login_user, logout_user, login_required
from itsdangerous import Serializer
from itsdangerous.exc import BadSignature
from app import app
from app.utils.render import render
from app.utils.login_as import is_vandal
from app.utils.unicode_names import normalize
from app.models.user import Member
from app.models.priv import Group
from app.forms.login_as import LoginAsForm


@app.route("/admin/vandalisme", methods=['GET', 'POST'])
@login_required
def adm_login_as():
    """ Show a basic form and login as arbitrary user when asked """

    # Basic permission
    if (not current_user.priv("misc.arbitrary-login") and
        not current_user.priv("misc.community-login")):
        abort(403)
    if is_vandal():
        flash("Vous êtes déjà authentifié", "error")
        return redirect(url_for('index'))

    # Handle form
    form = LoginAsForm()
    if form.validate_on_submit():
        norm = normalize(form.username.data)
        user = Member.query.filter_by(norm=norm).one()
        if user is None:
            flash("Utilisateur invalide", "error")
            return render('admin/login_as.html', form=form)

        # Apply for community login
        g = Group.query.filter_by(name="Compte communautaire").one()
        is_community = g in user.groups
        if not is_community and not current_user.priv("misc.arbitrary-login"):
            abort(403)

        # Create a safe token to flee when needed
        s = Serializer(app.config["SECRET_KEY"])
        vandal_token = s.dumps(current_user.id)

        # Login and display some messages
        login_user(user)
        if user.name == "GLaDOS":
            flash("Vous espérez quoi exactement ? Survivre ? "
                "Dans ce cas, évitez de me faire du mal.")
        else:
            flash(f"Connecté en tant que {user.name}")

        # Return the response
        resp = make_response(redirect(url_for('index')))
        resp.set_cookie('vandale', vandal_token)
        return resp

    # Else return form
    return render('admin/login_as.html', form=form)

@app.route("/admin/vandalisme/fuir")
@login_required
def adm_logout_as():
    """ Log out as a vandalized user, login back as admin """
    s = Serializer(app.config["SECRET_KEY"])

    vandal_token = request.cookies.get('vandale')
    if vandal_token is None:
        abort(403)

    try:
        id = s.loads(vandal_token)
    except BadSignature:
        flash("Vous avez vraiment agi de manière stupide.", "error")
        abort(403)

    user = Member.query.get(id)
    logout_user()
    login_user(user)

    if request.referrer:
        resp = make_response(redirect(request.referrer))
    else:
        resp = make_response(redirect(url_for('index')))

    resp.set_cookie('vandale', '', expires=0)
    return resp
