from flask_login import current_user
from wtforms.validators import ValidationError, StopValidation
from werkzeug.utils import secure_filename
from app.utils.filesize import filesize
from PIL import Image
import re


def optional(form, files):
    if(len(files.data) == 0 or files.data[0].filename == ""):
        raise StopValidation()


def count(form, files):
    if current_user.is_authenticated:
        if current_user.priv("misc.no-upload-limits"):
            return
        if len(files.data) > 100:  # 100 files for a authenticated user
            raise ValidationError("100 fichiers maximum autorisés")
    else:
        if len(files.data) > 3:
            raise ValidationError("3 fichiers maximum autorisés")


def extension(form, files):
    valid_extensions = [
        "g[123][a-z]|cpa|c1a|fxi|cat|mcs|xcp|fls",  # Casio files
        "png|jpg|jpeg|bmp|tiff|gif|xcf",  # Images
        "[ch](pp|\+\+|xx)?|s|py|bide|lua|lc",  # Source code
        "txt|md|tex|pdf|odt|ods|docx|xlsx",  # Office files
        "zip|7z|tar|bz2?|t?gz|xz|zst",  # Archives
    ]
    r = re.compile("|".join(valid_extensions), re.IGNORECASE)
    errors = []

    for f in files.data:
        name = secure_filename(f.filename)
        ext = name.split(".")[-1]
        if not r.fullmatch(ext):
            errors.append("." + ext)

    if len(errors) > 0:
        raise ValidationError("Extension(s) invalide(s)"
            f"({', '.join(errors)})")


def size(form, files):
    """There is no global limit to file sizes"""
    size = sum([filesize(f) for f in files.data])
    if current_user.is_authenticated:
        if current_user.priv("misc.no-upload-limits"):
            return
        if size > 5e6:  # 5 Mo per comment for an authenticated user
            raise ValidationError("Fichiers trop lourds (max 5 Mo)")
    else:
        if size > 500e3:  # 500 ko per comment for a guest
            raise ValidationError("Fichiers trop lourds (max 500 ko)")


def namelength(form, files):
    errors = []
    for f in files.data:
        name = secure_filename(f.filename)
        if len(name) > 64:
            errors.append(f.filename)
    if len(errors) > 0:
        raise ValidationError("Noms trop longs, 64 caractères max "
            f"({', '.join(errors)})")


def is_image(form, avatar):
    try:
        Image.open(avatar.data)
    except IOError:
        raise ValidationError("Avatar invalide")


def avatar_size(form, file):
    if filesize(file.data) > 200e3:
        raise ValidationError("Fichier trop lourd (max 200 ko)")
