/* 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.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.tools.junction.JunctionChangeEngine;
import net.fichotheque.tools.junction.TieBuffer;
import net.mapeadores.util.logging.ErrorMessageException;
import net.mapeadores.util.request.RequestMap;
import net.fichotheque.junction.JunctionEditor;


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

    public final static String COMMANDNAME = "MotclePonderation";
    public final static String COMMANDKEY = "_ THS-14";
    private Motcle motcle;
    private final Map<String, PonderationByCorpus> ponderationByCorpusMap = new HashMap<String, PonderationByCorpus>();

    public MotclePonderationCommand(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();
            JunctionChangeEngine junctionChangeEngine = JunctionChangeEngine.appendOrWeightReplaceEngine(motcle);
            for (PonderationByCorpus ponderationByCorpus : ponderationByCorpusMap.values()) {
                for (TieBuffer tieBuffer : ponderationByCorpus.getTieBufferList()) {
                    junctionChangeEngine.addTie(tieBuffer);
                }
            }
            junctionEditor.updateJunctions(motcle, junctionChangeEngine.toJunctionChanges());
        }
        putResultObject(THESAURUS_OBJ, motcle.getThesaurus());
        putResultObject(MOTCLE_OBJ, motcle);
        setDone("_ done.thesaurus.motcleponderation");
    }

    @Override
    protected void checkParameters() throws ErrorMessageException {
        motcle = requestHandler.getMandatoryMotcle();
        checkSubsetAdmin(motcle.getThesaurus());
        Set<String> wrongCorpusSet = new HashSet<String>();
        String mode = "";
        for (String paramName : requestHandler.getParameterNameSet()) {
            int idx = paramName.indexOf('_');
            if (idx == -1) {
                continue;
            }
            try {
                int id = Integer.parseInt(paramName.substring(idx + 1));
                String weightString = requestHandler.getTrimedParameter(paramName);
                int weight = 1;
                if (!weightString.isEmpty()) {
                    weight = Integer.parseInt(weightString);
                }
                if (weight < 1) {
                    continue;
                }
                String corpusName = paramName.substring(0, idx);
                if (wrongCorpusSet.contains(corpusName)) {
                    continue;
                }
                PonderationByCorpus ponderationByCorpus = ponderationByCorpusMap.get(corpusName);
                if (ponderationByCorpus == null) {
                    Corpus corpus = fichotheque.getCorpus(corpusName);
                    if ((corpus == null) || (!getPermissionSummary().hasAccess(corpus))) {
                        wrongCorpusSet.add(corpusName);
                        continue;
                    }
                    ponderationByCorpus = new PonderationByCorpus(corpus);
                    ponderationByCorpusMap.put(corpusName, ponderationByCorpus);
                }
                ponderationByCorpus.add(id, mode, weight);
            } catch (NumberFormatException nfe) {
            }
        }
    }


    private static class PonderationByCorpus {

        private final Corpus corpus;
        private final List<TieBuffer> tieBufferList = new ArrayList<TieBuffer>();

        private PonderationByCorpus(Corpus corpus) {
            this.corpus = corpus;
        }

        private void add(int id, String mode, int weight) {
            FicheMeta ficheMeta = corpus.getFicheMetaById(id);
            if (ficheMeta != null) {
                tieBufferList.add(new TieBuffer(ficheMeta, mode, weight));
            }
        }

        private List<TieBuffer> getTieBufferList() {
            return tieBufferList;
        }

        private Corpus getCorpus() {
            return corpus;
        }

    }

}
