package org.mte.numecoeval.expositiondonneesentrees.infrastructure.helper;

import org.apache.commons.csv.CSVRecord;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDate;

public class CSVHelper {

    private CSVHelper() {
    }

    /**
     * Renvoie la valeur de la colonne {@param mainName} dans le {@param csvRecord}.
     * Si le {@param mainName} n'est pas mappé dans le {@link CSVRecord}, la liste des noms alternatifs est utilisée.
     * Si aucune colonne n'est mappée ou que la liste alternative est vide, la valeur {@code null} est renvoyée.
     * @param csvRecord La ligne de CSV à traiter
     * @param mainName Le nom de la colonne souhaitée en 1er
     * @param alternativeNames Les noms de colonnes alternatifs à utiliser, peut être vide
     * @return La valeur de la 1er colonne correctement mappée sur la ligne de CSV, {@code null} en absence de mapping ou de contenue
     */
    public static String safeString(CSVRecord csvRecord, String mainName, String... alternativeNames) {
        if(csvRecord.isMapped(mainName)) {
            return StringUtils.defaultIfBlank(StringUtils.trim(csvRecord.get(mainName)), null);
        }

        for (String alternativeName : alternativeNames) {
            if(csvRecord.isMapped(alternativeName)) {
                return StringUtils.trim(csvRecord.get(alternativeName));
            }
        }
        return null;
    }

    public static LocalDate safeParseLocalDate(CSVRecord csvRecord, String field) {
        if(!csvRecord.isMapped(field)) {
            return null;
        }
        if(StringUtils.isEmpty(StringUtils.trim(csvRecord.get(field)))) {
            return null;
        }
        return LocalDate.parse(StringUtils.trim(csvRecord.get(field)));
    }

    public static Double safeDouble(CSVRecord csvRecord, String field) {
        if(!csvRecord.isMapped(field)) {
            return null;
        }
        if(!NumberUtils.isCreatable(StringUtils.trim(csvRecord.get(field)))) {
            return null;
        }
        return NumberUtils.toDouble(StringUtils.trim(csvRecord.get(field)));
    }

    public static Integer safeInteger(CSVRecord csvRecord, String field) {
        if(!csvRecord.isMapped(field)) {
            return null;
        }
        if(!NumberUtils.isCreatable(StringUtils.trim(csvRecord.get(field)))) {
            return null;
        }
        return NumberUtils.toInt(StringUtils.trim(csvRecord.get(field)));
    }

    /**
     * Vérifie si le fichier en paramètre est {@code null} ou vide ({@see MultipartFile#isEmpty()}).
     * @param fichierATester fichier à tester
     * @return {@code true} si le fichier est vide ou null sinon {@code false}
     */
    public static boolean fileIsNullOrEmpty(MultipartFile fichierATester) {
        return fichierATester == null || fichierATester.isEmpty();
    }
}
