/* BdfServer - Copyright (c) 202-2025 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package fr.exemole.bdfserver.tools.exportation.table;

import fr.exemole.bdfserver.api.exportation.table.FicheTableParameters;
import net.fichotheque.Fichotheque;
import net.fichotheque.FichothequeConstants;
import net.fichotheque.SubsetKey;
import net.fichotheque.corpus.metadata.CorpusField;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.exportation.table.FormatColDef;
import net.fichotheque.format.FormatSourceKey;
import net.fichotheque.format.SubsetPathKey;
import net.fichotheque.include.ExtendedIncludeKey;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.tools.format.FichothequeFormatDefBuilder;
import net.fichotheque.utils.TableDefUtils;
import net.mapeadores.util.format.FormatConstants;


/**
 *
 * @author Vincent Calame
 */
public final class BdfColDefs {

    private BdfColDefs() {

    }

    public static FormatColDef chrono(FichothequeFormatDefBuilder formatDefBuilder, String name, String patternMode) {
        formatDefBuilder.addSource(FormatSourceKey.newSpecialIncludeNameInstance(name));
        switch (patternMode) {
            case FicheTableParameters.STANDARD_PATTERNMODE:
            case FicheTableParameters.CODE_PATTERNMODE:
                formatDefBuilder.addFormatPattern("{iso}");
                formatDefBuilder.setCastType(FormatConstants.DATE_CAST);
                break;
            case FicheTableParameters.FORMSYNTAX_PATTERNMODE:
                formatDefBuilder.addFormatPattern("{formsyntax}");
                break;
            case FicheTableParameters.LABEL_PATTERNMODE:
                formatDefBuilder.addFormatPattern("{label}");
                break;
        }
        return TableDefUtils.toFormatColDef(name, formatDefBuilder.toFichothequeFormatDef());
    }

    public static FormatColDef liage(FichothequeFormatDefBuilder formatDefBuilder, String patternMode) {
        formatDefBuilder.addSource(FormatSourceKey.newSpecialIncludeNameInstance(FichothequeConstants.LIAGE_NAME));
        switch (patternMode) {
            case FicheTableParameters.STANDARD_PATTERNMODE:
            case FicheTableParameters.LABEL_PATTERNMODE:
                formatDefBuilder.addFormatPattern("{title}");
                formatDefBuilder.putStringValue(FormatConstants.SEPARATOR_PARAMKEY, ", ");
                break;
            case FicheTableParameters.CODE_PATTERNMODE:
                formatDefBuilder.addFormatPattern("{corpus}/{id}");
                break;
            case FicheTableParameters.FORMSYNTAX_PATTERNMODE:
                formatDefBuilder.addFormatPattern("{formsyntax}");
                break;
        }
        return TableDefUtils.toFormatColDef(FichothequeConstants.LIAGE_NAME, formatDefBuilder.toFichothequeFormatDef());
    }

    public static FormatColDef corpusField(FichothequeFormatDefBuilder formatDefBuilder, CorpusField corpusField, String patternMode) {
        formatDefBuilder.addSource(FormatSourceKey.newFieldKeyInstance(corpusField.getFieldKey()));
        if (isWithIntegerCast(corpusField)) {
            formatDefBuilder.setCastType(FormatConstants.INTEGER_CAST);
        }
        switch (patternMode) {
            case FicheTableParameters.FORMSYNTAX_PATTERNMODE: {
                formatDefBuilder.addFormatPattern("{formsyntax}");
                break;
            }
            case FicheTableParameters.STANDARD_PATTERNMODE: {
                if (isWithSeparator(corpusField)) {
                    formatDefBuilder.putStringValue(FormatConstants.SEPARATOR_PARAMKEY, ", ");
                }
                switch (corpusField.getFicheItemType()) {
                    case CorpusField.AMOUNT_FIELD:
                        formatDefBuilder.addFormatPattern("{code}");
                        formatDefBuilder.setCastType(FormatConstants.MONEY_CAST);
                        break;
                    case CorpusField.NUMBER_FIELD:
                        formatDefBuilder.addFormatPattern("{label}");
                        break;
                }
                break;
            }
            case FicheTableParameters.LABEL_PATTERNMODE: {
                if (isWithSeparator(corpusField)) {
                    formatDefBuilder.putStringValue(FormatConstants.SEPARATOR_PARAMKEY, ", ");
                }
                switch (corpusField.getFicheItemType()) {
                    case CorpusField.AMOUNT_FIELD:
                    case CorpusField.NUMBER_FIELD:
                    case CorpusField.COUNTRY_FIELD:
                    case CorpusField.LANGUAGE_FIELD:
                    case CorpusField.DATE_FIELD:
                        formatDefBuilder.addFormatPattern("{label}");
                        break;
                }
                break;
            }
            case FicheTableParameters.CODE_PATTERNMODE: {
                switch (corpusField.getFicheItemType()) {
                    case CorpusField.AMOUNT_FIELD:
                    case CorpusField.NUMBER_FIELD:
                    case CorpusField.COUNTRY_FIELD:
                    case CorpusField.LANGUAGE_FIELD:
                        formatDefBuilder.addFormatPattern("{code}");
                        break;
                }
                break;
            }
        }
        return TableDefUtils.toFormatColDef(corpusField.getFieldString(), formatDefBuilder.toFichothequeFormatDef());
    }

    public static FormatColDef subsetIncludeField(FichothequeFormatDefBuilder formatDefBuilder, ExtendedIncludeKey includeKey, String patternMode, Fichotheque fichotheque, SubsetPathKey masterPath) {
        if ((includeKey.isMaster()) && (masterPath != null)) {
            formatDefBuilder.addSource(FormatSourceKey.newIncludeKeyInstance(includeKey.getRootIncludeKey(), masterPath));
        } else {
            formatDefBuilder.addSource(FormatSourceKey.newIncludeKeyInstance(includeKey.getRootIncludeKey()));
        }
        SubsetKey subsetKey = includeKey.getSubsetKey();
        if (subsetKey.isThesaurusSubset()) {
            boolean isIdalpha = isIdalpha(fichotheque, subsetKey);
            switch (patternMode) {
                case FicheTableParameters.STANDARD_PATTERNMODE:
                case FicheTableParameters.LABEL_PATTERNMODE:
                    if (isIdalpha) {
                        formatDefBuilder.addFormatPattern("{idalpha} – {label}");
                    } else {
                        formatDefBuilder.addFormatPattern("{label}");
                    }
                    break;
                case FicheTableParameters.CODE_PATTERNMODE:
                    if (isIdalpha) {
                        formatDefBuilder.addFormatPattern("{idalpha}");
                    } else {
                        formatDefBuilder.addFormatPattern("{id}");
                    }
                    break;
                case FicheTableParameters.FORMSYNTAX_PATTERNMODE:
                    formatDefBuilder.addFormatPattern("{formsyntax}");
                    break;
            }
        } else if (subsetKey.isCorpusSubset()) {
            switch (patternMode) {
                case FicheTableParameters.STANDARD_PATTERNMODE:
                case FicheTableParameters.LABEL_PATTERNMODE:
                    formatDefBuilder.addFormatPattern("{title}");
                    formatDefBuilder.putStringValue(FormatConstants.SEPARATOR_PARAMKEY, ", ");
                    break;
                case FicheTableParameters.CODE_PATTERNMODE:
                    formatDefBuilder.addFormatPattern("{id}");
                    break;
                case FicheTableParameters.FORMSYNTAX_PATTERNMODE:
                    formatDefBuilder.addFormatPattern("{formsyntax}");
                    break;
            }
        } else {
            switch (patternMode) {
                case FicheTableParameters.STANDARD_PATTERNMODE:
                case FicheTableParameters.CODE_PATTERNMODE:
                case FicheTableParameters.LABEL_PATTERNMODE:
                    break;
                case FicheTableParameters.FORMSYNTAX_PATTERNMODE:
                    formatDefBuilder.addFormatPattern("{formsyntax}");
                    break;
            }
        }
        return TableDefUtils.toFormatColDef(includeKey.getKeyString(), formatDefBuilder.toFichothequeFormatDef());
    }

    private static boolean isWithSeparator(CorpusField corpusField) {
        switch (corpusField.getCategory()) {
            case FieldKey.INFO_CATEGORY:
                return true;
            case FieldKey.SPECIAL_CATEGORY:
                switch (corpusField.getFieldString()) {
                    case FieldKey.SPECIAL_OWNERS:
                        return true;

                }
            default:
                return false;
        }
    }

    private static boolean isWithIntegerCast(CorpusField corpusField) {
        switch (corpusField.getFieldString()) {
            case FieldKey.SPECIAL_ID:
                return true;
            default:
                return false;

        }
    }

    private static boolean isIdalpha(Fichotheque fichotheque, SubsetKey subsetKey) {
        Thesaurus thesaurus = (Thesaurus) fichotheque.getSubset(subsetKey);
        if (thesaurus != null) {
            return thesaurus.isIdalphaType();
        } else {
            return false;
        }
    }

}
