/* BdfServer_Commands - Copyright (c) 2011-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.commands.corpus;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.BdfServerConstants;
import fr.exemole.bdfserver.api.EditSession;
import fr.exemole.bdfserver.api.interaction.Domains;
import fr.exemole.bdfserver.api.ui.IncludeUi;
import fr.exemole.bdfserver.api.ui.UiComponents;
import fr.exemole.bdfserver.tools.externalsource.CoreExternalSourceCatalog;
import fr.exemole.bdfserver.tools.instruction.AbstractBdfCommand;
import fr.exemole.bdfserver.tools.instruction.BdfErrors;
import fr.exemole.bdfserver.tools.ui.components.IncludeUiBuilder;
import java.text.ParseException;
import net.fichotheque.Subset;
import net.fichotheque.SubsetKey;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.include.ExtendedIncludeKey;
import net.fichotheque.include.IncludeKey;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.thesaurus.policies.DynamicEditPolicy;
import net.mapeadores.util.logging.ErrorMessageException;
import net.mapeadores.util.request.RequestMap;
import net.mapeadores.util.text.StringUtils;


/**
 *
 * @author Vincent Calame
 */
public class SubsetIncludeCreationCommand extends AbstractBdfCommand {

    public final static String COMMANDNAME = "SubsetIncludeCreation";
    public final static String COMMANDKEY = "_ CRP-12";
    public final static String SUBSET_PARAMNAME = "subset";
    public final static String MASTERINCLUDE_PARAMNAME = "masterinclude";
    public final static String WEIGHTFILTER_PARAMNAME = "weightfilter";
    public final static String MODE_PARAMNAME = "mode";
    public final static String NO_WEIGHTFILTER_PARAMVALUE = "0";
    public final static String YES_WEIGHTFILTER_PARAMVALUE = "1";
    public final static String WEIGHTFILTERVALUE_PARAMNAME = "weightfiltervalue";
    private Corpus corpus;
    private UiComponents uiComponents;
    private Subset subset;
    private ExtendedIncludeKey includeKey;

    public SubsetIncludeCreationCommand(BdfServer bdfServer, RequestMap requestMap) {
        super(bdfServer, requestMap);
    }

    @Override
    public boolean needSynchronisation() {
        return true;
    }

    @Override
    protected void doCommand() {
        boolean done;
        try (EditSession session = startEditSession(Domains.CORPUS, COMMANDNAME)) {
            done = session.getBdfServerEditor().putComponentUi(uiComponents, buildIncludeUi());
        }
        putResultObject(CORPUS_OBJ, corpus);
        if (done) {
            setDone("_ done.corpus.subsetincludecreation", includeKey);
        }
    }

    @Override
    protected void checkParameters() throws ErrorMessageException {
        corpus = requestHandler.getMandatoryCorpus();
        checkSubsetAdmin(corpus);
        String subsetString = getMandatory(SUBSET_PARAMNAME);
        SubsetKey subsetKey = null;
        try {
            subsetKey = SubsetKey.parse(subsetString);
        } catch (java.text.ParseException pe) {
            throw BdfErrors.wrongParameterValue(SUBSET_PARAMNAME, subsetString);
        }
        subset = bdfServer.getFichotheque().getSubset(subsetKey);
        if (subset == null) {
            throw BdfErrors.unknownParameterValue(SUBSET_PARAMNAME, subsetString);
        }
        String weightFilterString = getMandatory(WEIGHTFILTER_PARAMNAME);
        int weightFilter = -1;
        if (weightFilterString.equals(YES_WEIGHTFILTER_PARAMVALUE)) {
            String weightFilterValue = getMandatory(WEIGHTFILTERVALUE_PARAMNAME);
            boolean error = false;
            try {
                weightFilter = Integer.parseInt(weightFilterValue);
                if (weightFilter < 1) {
                    error = true;
                }
            } catch (NumberFormatException nfe) {
                error = true;
            }
            if (error) {
                throw BdfErrors.error("_ error.wrong.weight", weightFilterValue);
            }
        } else if (!weightFilterString.equals(NO_WEIGHTFILTER_PARAMVALUE)) {
            throw BdfErrors.unknownParameterValue(WEIGHTFILTER_PARAMNAME, weightFilterString);
        }
        String mode = requestHandler.getTrimedParameter(MODE_PARAMNAME);
        if (!mode.isEmpty()) {
            try {
                StringUtils.checkTechnicalName(mode, false);
            } catch (ParseException pe) {
                throw BdfErrors.error("_ error.wrong.mode", mode);
            }
        }
        boolean master = false;
        Subset masterSubset = corpus.getMasterSubset();
        if (masterSubset != null) {
            master = requestHandler.isTrue(MASTERINCLUDE_PARAMNAME);
        }
        try {
            includeKey = ExtendedIncludeKey.newInstance(IncludeKey.newInstance(subsetKey, mode, weightFilter), master);
        } catch (IllegalArgumentException iae) {
            throw BdfErrors.unknownParameterValue(SUBSET_PARAMNAME, subsetString);
        }
        uiComponents = bdfServer.getUiManager().getMainUiComponents(corpus);
        if (uiComponents.contains(includeKey.getKeyString())) {
            throw BdfErrors.error("_ error.existing.include", includeKey.getKeyString());
        }
    }

    private IncludeUi buildIncludeUi() {
        IncludeUiBuilder includeUiBuilder = IncludeUiBuilder.initSubset(includeKey);
        if (subset instanceof Thesaurus) {
            Thesaurus thesaurus = (Thesaurus) subset;
            if (thesaurus.isBabelienType()) {
                DynamicEditPolicy policy = bdfServer.getPolicyManager().getPolicyProvider().getDynamicEditPolicy(thesaurus);
                if (policy instanceof DynamicEditPolicy.External) {
                    String type = ((DynamicEditPolicy.External) policy).getExternalSourceDef().getType();
                    if (type.equals(CoreExternalSourceCatalog.FICHOTHEQUECORPUS_TYPENAME)) {
                        includeUiBuilder.putOption(BdfServerConstants.INPUTTYPE_OPTION, BdfServerConstants.INPUT_FICHESTYLE);
                    }
                }
            }
        }
        return includeUiBuilder.toIncludeUi();
    }

}
