/* 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.croisement.CroisementEditor;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.tools.croisement.CroisementChangeEngine;
import net.fichotheque.tools.croisement.LienBuffer;
import net.fichotheque.utils.FichothequeUtils;
import net.mapeadores.util.logging.ErrorMessageException;
import net.mapeadores.util.request.RequestMap;


/**
 *
 * @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)) {
            CroisementEditor croisementsEditor = session.getFichothequeEditor().getCroisementEditor();
            CroisementChangeEngine croisementChangeEngine = CroisementChangeEngine.appendOrWeightReplaceEngine(motcle);
            for (PonderationByCorpus ponderationByCorpus : ponderationByCorpusMap.values()) {
                List<LienBuffer> bufferList = ponderationByCorpus.getLienBufferList();
                int size = bufferList.size();
                for (int i = 0; i < size; i++) {
                    croisementChangeEngine.addLien(bufferList.get(i));
                }
            }
            croisementsEditor.updateCroisements(motcle, croisementChangeEngine.toCroisementChanges());
        }
        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 = FichothequeUtils.getCorpus(fichotheque, 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<LienBuffer> lienBufferList = new ArrayList<LienBuffer>();

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

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

        private List<LienBuffer> getLienBufferList() {
            return lienBufferList;
        }

        private Corpus getCorpus() {
            return corpus;
        }

    }

}
