/* FichothequeLib_Tools - Copyright (c) 2011-2023 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 net.fichotheque.tools.exportation.scrutari;

import java.text.ParseException;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import net.fichotheque.SubsetKey;
import net.fichotheque.corpus.metadata.FieldKey;
import net.fichotheque.exportation.scrutari.CorpusScrutariDef;
import net.fichotheque.format.FormatSourceKey;
import net.mapeadores.util.localisation.Langs;
import net.mapeadores.util.text.AccoladePattern;
import net.mapeadores.util.text.StringUtils;


/**
 *
 * @author Vincent Calame
 */
public class CorpusScrutariDefBuilder {

    private final SubsetKey corpusKey;
    private final Set<String> includeTokenSet = new LinkedHashSet<String>();
    private FormatSourceKey dateFormatSourceKey;
    private AccoladePattern hrefPattern;
    private String multilangMode;
    private String multilangParam;
    private String fieldGenerationSource = "";

    public CorpusScrutariDefBuilder(SubsetKey corpusKey) {
        this.corpusKey = corpusKey;
    }

    public CorpusScrutariDefBuilder setDateKey(FormatSourceKey dateFormatSourceKey) {
        this.dateFormatSourceKey = dateFormatSourceKey;
        return this;
    }

    public CorpusScrutariDefBuilder setDateKey(String s) throws ParseException, WrongFormatSourceKeyException {
        this.dateFormatSourceKey = parseDateKey(s);
        return this;
    }

    public CorpusScrutariDefBuilder setHrefPattern(AccoladePattern hrefPattern) {
        this.hrefPattern = hrefPattern;
        return this;
    }

    public CorpusScrutariDefBuilder setLanguiMode() {
        this.multilangMode = CorpusScrutariDef.LANGUI_MODE;
        this.multilangParam = null;
        return this;
    }

    public CorpusScrutariDefBuilder setThesaurusMode(SubsetKey thesaurusKey) {
        if (!thesaurusKey.isThesaurusSubset()) {
            throw new IllegalArgumentException("!thesaurusKey.isThesaurusSubset()");
        }
        this.multilangMode = CorpusScrutariDef.THESAURUS_MODE;
        this.multilangParam = thesaurusKey.getSubsetName();
        return this;
    }

    public CorpusScrutariDefBuilder setFieldGenerationSource(String source) {
        if (source == null) {
            source = "";
        }
        this.fieldGenerationSource = source;
        return this;
    }

    public CorpusScrutariDefBuilder setFieldMode(FieldKey fieldKey) {
        this.multilangMode = CorpusScrutariDef.FIELD_MODE;
        this.multilangParam = fieldKey.getKeyString();
        return this;
    }

    public CorpusScrutariDefBuilder setCustomMode(Langs langs) {
        this.multilangMode = CorpusScrutariDef.CUSTOM_MODE;
        this.multilangParam = langs.toString(";");
        return this;
    }

    public CorpusScrutariDefBuilder setMultilang(String multilangMode, String multilangParam) {
        this.multilangMode = multilangMode;
        this.multilangParam = multilangParam;
        return this;
    }

    public CorpusScrutariDefBuilder addIncludeToken(String includeToken) {
        if ((includeToken != null) && (includeToken.length() > 0)) {
            includeTokenSet.add(includeToken);
        }
        return this;
    }

    public CorpusScrutariDefBuilder parseIncludeTokens(String includeTokens) {
        if (includeTokens != null) {
            String[] tokens = StringUtils.getTechnicalTokens(includeTokens, true);
            for (String token : tokens) {
                includeTokenSet.add(token);
            }
        }
        return this;
    }

    public CorpusScrutariDef toCorpusScrutariDef() {
        List<String> includeTokenList = StringUtils.toList(includeTokenSet);
        return new InternalCorpusScrutariDef(corpusKey, dateFormatSourceKey, fieldGenerationSource, hrefPattern, multilangMode, multilangParam, includeTokenList);
    }

    public static CorpusScrutariDefBuilder init(SubsetKey corpusKey) {
        return new CorpusScrutariDefBuilder(corpusKey);
    }

    public static FormatSourceKey parseDateKey(String s) throws ParseException, WrongFormatSourceKeyException {
        if (s.equals("date_creation")) {
            return FormatSourceKey.DATE_CREATION;
        }
        if (s.equals("date_modification")) {
            return FormatSourceKey.DATE_MODIFICATION;
        }
        FieldKey fieldKey = FieldKey.parse(s);
        switch (fieldKey.getCategory()) {
            case FieldKey.PROP_CATEGORY:
            case FieldKey.INFO_CATEGORY:
                return FormatSourceKey.newFieldKeyInstance(fieldKey);
            default:
                throw new WrongFormatSourceKeyException();
        }
    }


    private static class InternalCorpusScrutariDef implements CorpusScrutariDef {

        private final SubsetKey corpusKey;
        private final FormatSourceKey dateFormatSourceKey;
        private final String fieldGenerationSource;
        private final AccoladePattern hrefPattern;
        private final String multilangMode;
        private final String multilangParam;
        private final List<String> includeTokenList;


        private InternalCorpusScrutariDef(SubsetKey corpusKey, FormatSourceKey dateFormatSourceKey,
                String fieldGenerationSource, AccoladePattern hrefPattern, String multilangMode, String multilangParam, List<String> includeTokenList) {
            this.corpusKey = corpusKey;
            this.dateFormatSourceKey = dateFormatSourceKey;
            this.fieldGenerationSource = fieldGenerationSource;
            this.hrefPattern = hrefPattern;
            this.multilangMode = multilangMode;
            this.multilangParam = multilangParam;
            this.includeTokenList = includeTokenList;
        }

        @Override
        public String getFieldGenerationSource() {
            return fieldGenerationSource;
        }

        @Override
        public SubsetKey getCorpusKey() {
            return corpusKey;
        }

        @Override
        public FormatSourceKey getDateFormatSourceKey() {
            return dateFormatSourceKey;
        }

        @Override
        public AccoladePattern getHrefPattern() {
            return hrefPattern;
        }

        @Override
        public String getMultilangMode() {
            return multilangMode;
        }

        @Override
        public String getMultilangParam() {
            return multilangParam;
        }

        @Override
        public List<String> getIncludeTokenList() {
            return includeTokenList;
        }

    }

}
