from wtforms.validators import ValidationError
from app.utils.valid_name import valid_name
from app.models.user import User, Member
import app.utils.ldap as ldap
from app.utils.unicode_names import normalize
from config import V5Config


def valid(form, name):
    valid = valid_name(name.data)
    default = "Nom d'utilisateur invalide (erreur interne)"
    msg = {
        "too-short":
            "Le nom d'utilisateur doit faire au moins "
            f"{User.NAME_MINLEN} caractères.",
        "too-long":
            "Le nom d'utilisateur doit faire au plus "
            f"{User.NAME_MAXLEN} caractères.",
        "cant-normalize":
            "Ce nom d'utilisateur contient des caractères interdits. Les "
            "caractères autorisés sont les lettres, lettres accentuées, "
            'chiffres ainsi que "-" (tiret), "." (point), "~" (tilde) et '
            '"_" (underscore).',
        "no-letter":
            "Le nom d'utilisateur doit contenir au moins une lettre.",
        "forbidden":
            "Ce nom d'utilisateur est interdit."
    }
    if valid is not True:
        err = ' '.join(msg.get(code, default) for code in valid)
        raise ValidationError(err)


def available(form, name):
    # If the name is invalid, name_valid() will return a meaningful message
    try:
        norm = normalize(name.data)
    except ValueError:
        return

    member = Member.query.filter_by(norm=norm).first()
    if member is not None:
        raise ValidationError("Ce nom d'utilisateur est indisponible.")

    # Double check with LDAP if needed
    if V5Config.USE_LDAP:
        member = ldap.get_member(norm)
        if member is not None:
            raise ValidationError("Ce nom d'utilisateur est indisponible.")
