/* BdfServer_Get - Copyright (c) 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.get.access.v1;

import fr.exemole.bdfserver.api.interaction.InteractionConstants;
import fr.exemole.bdfserver.get.access.AccessGate;
import fr.exemole.bdfserver.tools.instruction.AbstractUtilRequestHandler;
import fr.exemole.bdfserver.tools.instruction.BdfErrors;
import fr.exemole.bdfserver.tools.subsettree.TreeUtils;
import java.util.Collection;
import java.util.Comparator;
import java.util.function.Predicate;
import net.fichotheque.Subset;
import net.fichotheque.SubsetKey;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.FicheMeta;
import net.fichotheque.corpus.Fiches;
import net.fichotheque.selection.SelectionContext;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.tools.corpus.FichesBuilder;
import net.fichotheque.tools.selection.SelectionEngines;
import net.fichotheque.utils.selection.FicheSelectorBuilder;
import net.fichotheque.utils.selection.MotcleSelectorBuilder;
import net.mapeadores.util.logging.ErrorMessageException;
import net.mapeadores.util.request.RequestMap;


/**
 *
 * @author Vincent Calame
 */
public class AccessGateRequestHandler extends AbstractUtilRequestHandler {

    private final AccessGate accessGate;

    public AccessGateRequestHandler(AccessGate accessGate, RequestMap requestMap) {
        super(accessGate.getBdfServer(), requestMap);
        this.accessGate = accessGate;
    }

    public AccessGate getAccessGate() {
        return accessGate;
    }

    @Override
    protected void store(String paramName, String paramValue) {

    }

    public Comparator<FicheMeta> getComparator() throws ErrorMessageException {
        return getComparator(accessGate.getLang());
    }

    public FicheMeta getFiche() throws ErrorMessageException {
        FicheMeta ficheMeta = getMandatoryFicheMeta();
        if (!accessGate.getFichePredicate().test(ficheMeta)) {
            throw BdfErrors.unknownParameterValue(InteractionConstants.ID_PARAMNAME, String.valueOf(ficheMeta.getId()));
        }
        return ficheMeta;
    }

    public Motcle getMotcle() throws ErrorMessageException {
        Motcle motcle = getMandatoryMotcle();
        if (!accessGate.getMotclePredicate().test(motcle)) {
            throw BdfErrors.unknownParameterValue(InteractionConstants.ID_PARAMNAME, String.valueOf(motcle.getId()));
        }
        return motcle;
    }

    public Fiches getFiches() throws ErrorMessageException {
        SelectionContext selectionContext = accessGate.getSelectionContext();
        String selection = requestMap.getParameter(InteractionConstants.SELECTION_PARAMNAME);
        String xml = requestMap.getParameter(InteractionConstants.XML_PARAMNAME);
        FichesBuilder fichesBuilder = FichesBuilder.init(getComparator())
                .initSubsetKeyOrder(TreeUtils.getCorpusKeyList(bdfServer));
        if ((selection != null) || (xml != null)) {
            FicheSelectorBuilder selectorBuilder = FicheSelectorBuilder.init(selectionContext);
            if (selection != null) {
                populateFromSelection(selectorBuilder);
            } else {
                populateFromXml(selectorBuilder);
            }
            fichesBuilder.populate(selectorBuilder.toFicheSelector());
        } else {
            Predicate<FicheMeta> fichePredicate = accessGate.getFichePredicate();
            for (Corpus corpus : bdfServer.getFichotheque().getCorpusList()) {
                if (accessGate.getSubsetPredicate().test(corpus)) {
                    for (FicheMeta ficheMeta : corpus.getFicheMetaList()) {
                        if (fichePredicate.test(ficheMeta)) {
                            fichesBuilder.add(ficheMeta);
                        }
                    }
                }
            }
        }
        return fichesBuilder.toFiches();
    }

    public Thesaurus getThesaurus() throws ErrorMessageException {
        Thesaurus thesaurus = getMandatoryThesaurus();
        if (!accessGate.getSubsetPredicate().test(thesaurus)) {
            throw BdfErrors.unknownParameterValue(SubsetKey.CATEGORY_THESAURUS_STRING, thesaurus.getSubsetName());
        }
        return thesaurus;
    }

    public Subset getSubset() throws ErrorMessageException {
        Subset subset = getMandatorySubset();
        if (!accessGate.getSubsetPredicate().test(subset)) {
            throw BdfErrors.unknownParameterValue(InteractionConstants.SUBSET_PARAMNAME, subset.getSubsetKeyString());
        }
        return subset;
    }

    public Collection<FicheMeta> getFicheArray() throws ErrorMessageException {
        SelectionContext selectionContext = accessGate.getSelectionContext();
        Comparator<FicheMeta> comparator = getComparator();
        FicheSelectorBuilder selectorBuilder = FicheSelectorBuilder.init(selectionContext);
        populateFromXml(selectorBuilder);
        return SelectionEngines.run(selectionContext, selectorBuilder.toFicheSelector(), comparator);
    }

    public Collection<Motcle> getMotcleArray() throws ErrorMessageException {
        SelectionContext selectionContext = accessGate.getSelectionContext();
        MotcleSelectorBuilder selectorBuilder = MotcleSelectorBuilder.init(selectionContext);
        populateFromXml(selectorBuilder);
        return SelectionEngines.run(selectionContext, null, selectorBuilder.toMotcleSelector(), null);
    }

    public static AccessGateRequestHandler init(AccessGate accessGate, RequestMap requestMap) {
        return new AccessGateRequestHandler(accessGate, requestMap);
    }

}
