from wtforms.validators import ValidationError
from flask_login import current_user
from math import log


def is_strong(form, password):
    # To avoid errors in forms where password is optionnal
    if len(password.data) == 0:
        return

    def entropy(password):
        """Estimate entropy of a password, in bits"""
        # If you edit this function, please edit accordingly the JS one
        # in static/script/entropy.js
        chars = [
            "abcdefghijklmnopqrstuvwxyz",
            "ABCDFEGHIJKLMNOPQRSTUVWXYZ",
            "0123456789",
            " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~§",  # OWASP special chars
            "áàâéèêíìîóòôúùûç",
        ]
        used = set()
        for c in password:
            for i in chars:
                if c in i:
                    used.add(i)
        return log(len(''.join(used)) ** len(password), 2)

    if entropy(password.data) < 60:
        raise ValidationError("Mot de passe pas assez complexe")


def old_password(form, field):
    if field.data:
        if not form.old_password.data:
            raise ValidationError('Votre ancien mot de passe est requis pour cette modification.')
        if not current_user.check_password(form.old_password.data):
            raise ValidationError('Mot de passe actuel erroné.')
