/* 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.List;
import net.fichotheque.exportation.balayage.BalayageConstants;
import net.fichotheque.exportation.balayage.BalayageOutput;
import net.fichotheque.exportation.balayage.BalayageUnit;
import net.fichotheque.utils.BalayageUtils;
import net.mapeadores.util.localisation.Langs;
import net.mapeadores.util.text.AccoladePattern;
import net.mapeadores.util.text.StringUtils;


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

    private final List<InternalOutputParam> outputParamList = new ArrayList<InternalOutputParam>();
    private String name = "";
    private String langOption = BalayageConstants.LANGOPTION_UNKNOWN;
    private String xsltPath = "";
    private AccoladePattern pattern = null;
    private AccoladePattern outputPathPattern = null;
    private String reversePath = "";
    private String mode = "";
    private boolean cleanBefore = false;
    private boolean includeOutput = false;
    private Langs customLangs = null;
    private String posttransform = "";

    public BalayageOutputBuilder() {
    }

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

    public BalayageOutputBuilder setXsltPath(String xsltPath) {
        this.xsltPath = StringUtils.nullTrim(xsltPath);
        return this;
    }

    public BalayageOutputBuilder setMode(String mode) {
        this.mode = StringUtils.nullTrim(mode);
        return this;
    }

    public BalayageOutputBuilder setCleanBefore(boolean cleanBefore) {
        this.cleanBefore = cleanBefore;
        return this;
    }

    public BalayageOutputBuilder setLangOption(String langOption) {
        langOption = BalayageConstants.checkLangOption(langOption);
        this.langOption = langOption;
        return this;
    }

    public BalayageOutputBuilder setIncludeOutput(boolean includeOutput) {
        this.includeOutput = includeOutput;
        return this;
    }

    public BalayageOutputBuilder setPattern(AccoladePattern pattern) {
        this.pattern = pattern;
        return this;
    }

    public BalayageOutputBuilder setOutputPathPattern(AccoladePattern outputPathPattern) {
        this.outputPathPattern = outputPathPattern;
        initReversePath();
        return this;
    }


    public BalayageOutputBuilder setCustomLangs(Langs customLangs) {
        this.customLangs = customLangs;
        return this;
    }

    public BalayageOutputBuilder setPosttransform(String posttransform) {
        this.posttransform = StringUtils.nullTrim(posttransform);
        return this;
    }

    public BalayageOutputBuilder addOutputParam(String name, String value) {
        outputParamList.add(new InternalOutputParam(name, value));
        return this;
    }

    public BalayageOutput toBalayageOutput(BalayageUnit balayageUnit) {
        List<BalayageOutput.Param> finalParamList = BalayageUtils.wrap(outputParamList.toArray(new BalayageOutput.Param[outputParamList.size()]));
        return new InternalOutput(balayageUnit, name, xsltPath, mode, cleanBefore, includeOutput,
                langOption, pattern, outputPathPattern, reversePath, customLangs, posttransform, finalParamList);
    }

    private void initReversePath() {
        if (outputPathPattern != null) {
            reversePath = StringUtils.getReversePath(outputPathPattern.toString());
        } else {
            reversePath = "";
        }
    }

    public static BalayageOutputBuilder init() {
        return new BalayageOutputBuilder();
    }


    private static class InternalOutput implements BalayageOutput {

        private final BalayageUnit balayageUnit;
        private final String name;
        private final String xsltPath;
        private final String langOption;
        private final AccoladePattern pattern;
        private final AccoladePattern outputPathPattern;
        private final String reversePath;
        private final String mode;
        private final boolean cleanBefore;
        private final boolean includeOutput;
        private final Langs customLangs;
        private final String posttransform;
        private final List<BalayageOutput.Param> paramList;

        private InternalOutput(BalayageUnit balayageUnit, String name, String xsltPath, String mode, boolean cleanBefore, boolean includeOutput,
                String langOption, AccoladePattern pattern, AccoladePattern outputPathPattern, String reversePath, Langs customLangs, String posttransform, List<BalayageOutput.Param> paramList) {
            this.balayageUnit = balayageUnit;
            this.name = name;
            this.xsltPath = xsltPath;
            this.mode = mode;
            this.cleanBefore = cleanBefore;
            this.includeOutput = includeOutput;
            this.langOption = langOption;
            this.pattern = pattern;
            this.outputPathPattern = outputPathPattern;
            this.reversePath = reversePath;
            this.customLangs = customLangs;
            this.posttransform = posttransform;
            this.paramList = paramList;
        }

        @Override
        public BalayageUnit getBalayageUnit() {
            return balayageUnit;
        }

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

        @Override
        public String getXsltPath() {
            return xsltPath;
        }

        @Override
        public AccoladePattern getPattern() {
            return pattern;
        }

        @Override
        public AccoladePattern getOutputPath() {
            return outputPathPattern;
        }

        @Override
        public String getMode() {
            return mode;
        }

        @Override
        public boolean isCleanBefore() {
            return cleanBefore;
        }

        @Override
        public String getLangOption() {
            return langOption;
        }

        @Override
        public String getReversePath() {
            return reversePath;
        }

        @Override
        public boolean isIncludeOutput() {
            return includeOutput;
        }

        @Override
        public Langs getCustomLangs() {
            return customLangs;
        }

        @Override
        public String getPosttransform() {
            return posttransform;
        }

        @Override
        public List<Param> getParamList() {
            return paramList;
        }

    }


    private static class InternalOutputParam implements BalayageOutput.Param {

        private final String name;
        private final String value;

        private InternalOutputParam(String name, String value) {
            this.name = name;
            this.value = value;
        }

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

        @Override
        public String getValue() {
            return value;
        }

    }

}
