/* BdfServer - Copyright (c) 2011-2024 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.balayage;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import net.fichotheque.exportation.balayage.BalayageOutput;
import net.fichotheque.exportation.balayage.BalayageUnit;
import net.fichotheque.selection.DocumentQuery;
import net.fichotheque.selection.FicheQuery;
import net.fichotheque.selection.IllustrationQuery;
import net.fichotheque.selection.MotcleQuery;
import net.fichotheque.utils.BalayageUtils;
import net.fichotheque.utils.SelectionUtils;
import net.mapeadores.util.annotation.Nullable;
import net.mapeadores.util.text.StringUtils;


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

    private final Set<String> modeSet = new LinkedHashSet<String>();
    private final Set<String> extensionSet = new LinkedHashSet<String>();
    private final List<BalayageOutputBuilder> outputBuilderList = new ArrayList<BalayageOutputBuilder>();
    private final String type;
    private String name = "";
    private String extractionPath = "";
    private boolean globalSelect = true;
    private FicheQuery ficheQuery = SelectionUtils.EMPTY_FICHEQUERY;
    private MotcleQuery motcleQuery = SelectionUtils.EMPTY_MOTCLEQUERY;
    private IllustrationQuery illustrationQuery = SelectionUtils.EMPTY_ILLUSTRATIONQUERY;
    private DocumentQuery documentQuery = SelectionUtils.EMPTY_DOCUMENTQUERY;

    public BalayageUnitBuilder(String type) {
        this.type = type;
    }

    public BalayageUnitBuilder setName(String name) {
        this.name = StringUtils.nullTrim(name);
        return this;
    }

    public BalayageUnitBuilder setGlobalSelect(boolean globalSelect) {
        this.globalSelect = globalSelect;
        return this;
    }

    public BalayageUnitBuilder setExtractionPath(String extractionPath) {
        this.extractionPath = StringUtils.nullTrim(extractionPath);
        return this;
    }

    public BalayageUnitBuilder addMode(String mode) {
        modeSet.add(mode);
        return this;
    }

    public BalayageUnitBuilder setFicheQuery(@Nullable FicheQuery ficheQuery) {
        if (ficheQuery == null) {
            this.ficheQuery = SelectionUtils.EMPTY_FICHEQUERY;
        } else {
            this.ficheQuery = ficheQuery;
        }
        return this;
    }

    public BalayageUnitBuilder setMotcleQuery(@Nullable MotcleQuery motcleQuery) {
        if (motcleQuery == null) {
            this.motcleQuery = SelectionUtils.EMPTY_MOTCLEQUERY;
        } else {
            this.motcleQuery = motcleQuery;
        }
        return this;
    }

    public BalayageUnitBuilder setIllustrationQuery(@Nullable IllustrationQuery illustrationQuery) {
        if (illustrationQuery == null) {
            this.illustrationQuery = SelectionUtils.EMPTY_ILLUSTRATIONQUERY;
        } else {
            this.illustrationQuery = illustrationQuery;
        }
        return this;
    }

    public BalayageUnitBuilder setDocumentQuery(@Nullable DocumentQuery documentQuery) {
        if (documentQuery == null) {
            this.documentQuery = SelectionUtils.EMPTY_DOCUMENTQUERY;
        } else {
            this.documentQuery = documentQuery;
        }
        return this;
    }

    public BalayageUnitBuilder addExtension(String s) {
        extensionSet.add(s);
        return this;
    }

    public BalayageOutputBuilder addOutputBuilder() {
        BalayageOutputBuilder iob = new BalayageOutputBuilder();
        outputBuilderList.add(iob);
        return iob;
    }

    public BalayageUnit toBalayageUnit() {
        List<String> modeList = StringUtils.toList(modeSet);
        List<String> extensionList = StringUtils.toList(extensionSet);
        InternalBalayageUnit balayageUnit = new InternalBalayageUnit(type, name, extractionPath, globalSelect, ficheQuery, motcleQuery, illustrationQuery, documentQuery, modeList, extensionList);
        int outputSize = outputBuilderList.size();
        BalayageOutput[] outputArray = new BalayageOutput[outputSize];
        for (int i = 0; i < outputSize; i++) {
            outputArray[i] = outputBuilderList.get(i).toBalayageOutput(balayageUnit);
        }
        balayageUnit.outputList = BalayageUtils.wrap(outputArray);
        return balayageUnit;
    }

    public static BalayageUnitBuilder init(String type) {
        return new BalayageUnitBuilder(type);
    }


    private static class InternalBalayageUnit implements BalayageUnit {

        private final String type;
        private final String name;
        private final String extractionPath;
        private boolean globalSelect = true;
        private final FicheQuery ficheQuery;
        private final MotcleQuery motcleQuery;
        private final IllustrationQuery illustrationQuery;
        private final DocumentQuery documentQuery;
        private final List<String> modeList;
        private final List<String> extensionList;
        private List<BalayageOutput> outputList;


        private InternalBalayageUnit(String type, String name, String extractionPath, boolean globalSelect,
                FicheQuery ficheQuery, MotcleQuery motcleQuery, IllustrationQuery illustrationQuery, DocumentQuery documentQuery,
                List<String> modeList, List<String> extensionList) {
            this.type = type;
            this.name = name;
            this.extractionPath = extractionPath;
            this.globalSelect = globalSelect;
            this.ficheQuery = ficheQuery;
            this.motcleQuery = motcleQuery;
            this.illustrationQuery = illustrationQuery;
            this.documentQuery = documentQuery;
            this.modeList = modeList;
            this.extensionList = extensionList;
        }

        @Override
        public String getName() {
            return name;
        }

        @Override
        public String getType() {
            return type;
        }

        @Override
        public boolean isGlobalSelect() {
            return globalSelect;
        }

        @Override
        public FicheQuery getFicheQuery() {
            return ficheQuery;
        }

        @Override
        public MotcleQuery getMotcleQuery() {
            return motcleQuery;
        }

        @Override
        public IllustrationQuery getIllustrationQuery() {
            return illustrationQuery;
        }

        @Override
        public DocumentQuery getDocumentQuery() {
            return documentQuery;
        }

        @Override
        public List<BalayageOutput> getOutputList() {
            return outputList;
        }

        @Override
        public List<String> getModeList() {
            return modeList;
        }

        @Override
        public List<String> getExtensionList() {
            return extensionList;
        }

        @Override
        public String getExtractionPath() {
            return extractionPath;
        }

    }

}
