/* BdfServer_Commands - Copyright (c) 2012-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.thesaurus;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.EditSession;
import fr.exemole.bdfserver.api.interaction.Domains;
import fr.exemole.bdfserver.tools.instruction.AbstractBdfCommand;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.include.IncludeKey;
import net.fichotheque.junction.JunctionEditor;
import net.fichotheque.permission.PermissionSummary;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.tools.junction.JunctionChangeEngine;
import net.fichotheque.tools.junction.TieBuffer;
import net.fichotheque.tools.parsers.junction.TieBufferParser;
import net.mapeadores.util.logging.ErrorMessageException;
import net.mapeadores.util.request.RequestMap;
import net.mapeadores.util.text.StringUtils;


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

    public final static String COMMANDNAME = "MotcleIndexation";
    public final static String COMMANDKEY = "_ THS-13";
    private Motcle motcle;
    private List<TieByCorpus> tieByCorpusList;

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

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

    @Override
    protected void doCommand() throws ErrorMessageException {
        try (EditSession session = startEditSession(Domains.THESAURUS, COMMANDNAME)) {
            JunctionEditor junctionEditor = session.getFichothequeEditor().getJunctionEditor();
            List<IncludeKey> scopeList = new ArrayList<IncludeKey>();
            for (TieByCorpus tieByCorpus : tieByCorpusList) {
                scopeList.add(IncludeKey.newInstance(tieByCorpus.corpus.getSubsetKey()));
            }
            JunctionChangeEngine junctionChangeEngine = JunctionChangeEngine.clearExistingEngine(motcle, scopeList);
            for (TieByCorpus tieByCorpus : tieByCorpusList) {
                for (TieBuffer tieBuffer : tieByCorpus.tieBufferList) {
                    junctionChangeEngine.addTie(tieBuffer);
                }
            }
            junctionEditor.updateJunctions(motcle, junctionChangeEngine.toJunctionChanges());
        }
        putResultObject(THESAURUS_OBJ, motcle.getThesaurus());
        putResultObject(MOTCLE_OBJ, motcle);
        setDone("_ done.thesaurus.motcleindexation");
    }

    @Override
    protected void checkParameters() throws ErrorMessageException {
        motcle = requestHandler.getMandatoryMotcle();
        checkSubsetAdmin(motcle.getThesaurus());
        PermissionSummary permissionSummary = getPermissionSummary();
        tieByCorpusList = new ArrayList<TieByCorpus>();
        for (Corpus corpus : fichotheque.getCorpusList()) {
            if (permissionSummary.hasAccess(corpus)) {
                String param_value = requestHandler.getTrimedParameter(corpus.getSubsetKeyString());
                if (!param_value.isEmpty()) {
                    tieByCorpusList.add(parse(corpus, param_value));
                }
            }
        }
    }

    private TieByCorpus parse(Corpus corpus, String chaine) {
        String[] tokens = StringUtils.getTechnicalTokens(chaine, false);
        List<TieBuffer> tieBufferList = new ArrayList<TieBuffer>();
        for (String token : tokens) {
            try {
                TieBuffer tieBuffer = TieBufferParser.parseId(corpus, token, null, -1);
                tieBufferList.add(tieBuffer);
            } catch (ParseException pe) {

            }
        }
        return new TieByCorpus(corpus, tieBufferList);
    }


    private static class TieByCorpus {

        private final Corpus corpus;
        private final List<TieBuffer> tieBufferList;

        private TieByCorpus(Corpus corpus, List<TieBuffer> tieBufferList) {
            this.corpus = corpus;
            this.tieBufferList = tieBufferList;
        }

    }

}
