/* BdfServer - Copyright (c) 2009-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.tools.balayage.engine;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.balayage.FileGenerationListener;
import fr.exemole.bdfserver.api.configuration.PathConfiguration;
import fr.exemole.bdfserver.tools.BdfServerUtils;
import java.io.File;
import java.util.List;
import javax.xml.transform.URIResolver;
import net.fichotheque.corpus.Fiches;
import net.fichotheque.corpus.SortConstants;
import net.fichotheque.exportation.balayage.BalayageDef;
import net.fichotheque.exportation.balayage.BalayageDescription;
import net.fichotheque.exportation.balayage.BalayageMode;
import net.fichotheque.extraction.ExtractParameters;
import net.fichotheque.extraction.ExtractionContext;
import net.fichotheque.selection.FicheQuery;
import net.fichotheque.selection.FichothequeQueries;
import net.fichotheque.selection.SelectionContext;
import net.fichotheque.tools.corpus.FichesBuilder;
import net.fichotheque.tools.extraction.builders.ExtractParametersBuilder;
import net.fichotheque.tools.permission.PermissionUtils;
import net.fichotheque.utils.EligibilityUtils;
import net.fichotheque.utils.TransformationUtils;
import net.fichotheque.utils.selection.FicheSelectorBuilder;
import net.mapeadores.util.localisation.Lang;
import net.mapeadores.util.localisation.LangContext;
import net.mapeadores.util.localisation.Langs;
import net.mapeadores.util.localisation.ListLangContextBuilder;


/**
 *
 * @author Vincent Calame
 */
public class BalayageParameters {

    private final BalayageDescription balayageDescription;
    private final BalayageDef balayageDef;
    private final BdfServer bdfServer;
    private final PathConfiguration pathConfiguration;
    private ExtractParameters extractParameters = null;
    private BalayageMode balayageMode;
    private BalayageLog balayageLog;
    private File balayageRootDirectory;
    private FileGenerationListener fileGenerationListener;
    private URIResolver customURIResolver;
    private Fiches selectedFiches;

    public BalayageParameters(BalayageDescription balayageDescription, BdfServer bdfServer, PathConfiguration pathConfiguration) {
        this.balayageDescription = balayageDescription;
        this.balayageDef = balayageDescription.getBalayageDef();
        this.bdfServer = bdfServer;
        this.pathConfiguration = pathConfiguration;
    }

    public BalayageMode getBalayageMode() {
        return balayageMode;
    }

    public BalayageParameters setBalayageMode(BalayageMode balayageMode) {
        this.balayageMode = balayageMode;
        return this;
    }

    public BalayageLog getBalayageLog() {
        return balayageLog;
    }

    public BalayageParameters setBalayageLog(BalayageLog balayageLog) {
        this.balayageLog = balayageLog;
        return this;
    }

    public BalayageDef getBalayageDef() {
        return balayageDef;
    }

    public BalayageDescription getBalayageDescription() {
        return balayageDescription;
    }

    public BdfServer getBdfServer() {
        return bdfServer;
    }

    public PathConfiguration getPathConfiguration() {
        return pathConfiguration;
    }

    public File getBalayageRootDirectory() {
        return balayageRootDirectory;
    }

    public BalayageParameters setBalayageRootDirectory(File balayageRootDirectory) {
        this.balayageRootDirectory = balayageRootDirectory;
        return this;
    }

    public ExtractParameters getExtractParameters() {
        if (extractParameters != null) {
            return extractParameters;
        }
        initExtractParameters();
        return extractParameters;
    }

    public Fiches getSelectedFiches() {
        if (extractParameters != null) {
            return selectedFiches;
        }
        initExtractParameters();
        return selectedFiches;
    }

    /**
     * @return the fileGenerationListener
     */
    public FileGenerationListener getFileGenerationListener() {
        return fileGenerationListener;
    }

    /**
     * @param fileGenerationListener the fileGenerationListener to set
     */
    public BalayageParameters setFileGenerationListener(FileGenerationListener fileGenerationListener) {
        this.fileGenerationListener = fileGenerationListener;
        return this;
    }

    public URIResolver getCustomURIResolver() {
        return customURIResolver;
    }

    public BalayageParameters setCustomURIResolver(URIResolver customURIResolver) {
        this.customURIResolver = customURIResolver;
        return this;
    }

    private void initExtractParameters() {
        LangContext langContext;
        Langs langs = balayageDef.getLangs();
        if (!langs.isEmpty()) {
            langContext = ListLangContextBuilder.build(langs);
        } else {
            langContext = bdfServer.getLangConfiguration().toLangContext();
        }
        this.selectedFiches = initSelectedFiches(langContext);
        ExtractionContext extractionContext = BdfServerUtils.initExtractionContextBuilder(bdfServer, langContext, PermissionUtils.FICHOTHEQUEADMIN_PERMISSIONSUMMARY).toExtractionContext();
        int extractVersion = TransformationUtils.getExtractVersion(balayageDef.getAttributes());
        this.extractParameters = ExtractParametersBuilder.init(extractionContext, extractVersion)
                .setWithEmpty(false)
                .setWithPosition(false)
                .setFichePredicate(selectedFiches)
                .toExtractParameters();
    }

    private Fiches initSelectedFiches(LangContext langContext) {
        Fiches fiches = null;
        FichothequeQueries fichothequeQueries = BdfServerUtils.resolveSelectionOptions(bdfServer, balayageDef.getSelectionOptions());
        List<FicheQuery> ficheQueryList = fichothequeQueries.getFicheQueryList();
        if (!ficheQueryList.isEmpty()) {
            Lang defaultLang = langContext.getDefaultLang();
            SelectionContext selectionContext = BdfServerUtils.initSelectionContextBuilder(bdfServer, defaultLang)
                    .setSubsetAccessPredicate(EligibilityUtils.ALL_SUBSET_PREDICATE)
                    .toSelectionContext();
            FicheSelectorBuilder ficheSelectorBuilder = FicheSelectorBuilder.init(selectionContext);
            for (FicheQuery ficheQuery : ficheQueryList) {
                ficheSelectorBuilder.add(ficheQuery);
            }
            fiches = FichesBuilder.build(SortConstants.NONE)
                    .populate(ficheSelectorBuilder.toFicheSelector())
                    .toFiches();
        }
        return fiches;
    }

    public static BalayageParameters init(BalayageDescription balayageDescription, BdfServer bdfServer, PathConfiguration pathConfiguration) {
        return new BalayageParameters(balayageDescription, bdfServer, pathConfiguration);
    }

}
