/* 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.croisement.CroisementEditor;
import net.fichotheque.include.IncludeKey;
import net.fichotheque.permission.PermissionSummary;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.tools.croisement.CroisementChangeEngine;
import net.fichotheque.tools.croisement.LienBuffer;
import net.fichotheque.tools.parsers.croisement.LienBufferParser;
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<CroisementByCorpus> croisementByCorpusList;

    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)) {
            CroisementEditor croisementEditor = session.getFichothequeEditor().getCroisementEditor();
            List<IncludeKey> scopeList = new ArrayList<IncludeKey>();
            for (CroisementByCorpus croisementByCorpus : croisementByCorpusList) {
                scopeList.add(IncludeKey.newInstance(croisementByCorpus.corpus.getSubsetKey()));
            }
            CroisementChangeEngine croisementChangeEngine = CroisementChangeEngine.clearExistingEngine(motcle, scopeList);
            for (CroisementByCorpus croisementByCorpus : croisementByCorpusList) {
                List<LienBuffer> lienBufferList = croisementByCorpus.croisementList;
                for (LienBuffer lienBuffer : lienBufferList) {
                    croisementChangeEngine.addLien(lienBuffer);
                }
            }
            croisementEditor.updateCroisements(motcle, croisementChangeEngine.toCroisementChanges());
        }
        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();
        croisementByCorpusList = new ArrayList<CroisementByCorpus>();
        for (Corpus corpus : fichotheque.getCorpusList()) {
            if (permissionSummary.hasAccess(corpus)) {
                String param_value = requestHandler.getTrimedParameter(corpus.getSubsetKeyString());
                if (!param_value.isEmpty()) {
                    croisementByCorpusList.add(parse(corpus, param_value));
                }
            }
        }
    }

    private CroisementByCorpus parse(Corpus corpus, String chaine) {
        String[] tokens = StringUtils.getTechnicalTokens(chaine, false);
        List<LienBuffer> lienBufferList = new ArrayList<LienBuffer>();
        for (String token : tokens) {
            try {
                LienBuffer lienBuffer = LienBufferParser.parseId(corpus, token, null, -1);
                lienBufferList.add(lienBuffer);
            } catch (ParseException pe) {

            }
        }
        return new CroisementByCorpus(corpus, lienBufferList);
    }


    private static class CroisementByCorpus {

        private final Corpus corpus;
        private final List<LienBuffer> croisementList;

        private CroisementByCorpus(Corpus corpus, List<LienBuffer> croisementList) {
            this.corpus = corpus;
            this.croisementList = croisementList;
        }

    }

}
