/* BdfServer_Get - Copyright (c) 2013-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.instructions.tables;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.exportation.table.TableExportParameters;
import fr.exemole.bdfserver.api.instruction.BdfParameters;
import fr.exemole.bdfserver.api.interaction.GetConstants;
import fr.exemole.bdfserver.api.interaction.InteractionConstants;
import fr.exemole.bdfserver.get.streamproducers.TableExportOdsProducer;
import fr.exemole.bdfserver.tools.BdfServerUtils;
import fr.exemole.bdfserver.tools.exportation.table.BdfTableExportUtils;
import fr.exemole.bdfserver.tools.exportation.table.TableExportParametersBuilder;
import fr.exemole.bdfserver.tools.instruction.BdfErrors;
import fr.exemole.bdfserver.tools.instruction.RequestHandler;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.function.Predicate;
import net.fichotheque.SubsetItem;
import net.fichotheque.exportation.table.SumCellConverter;
import net.fichotheque.exportation.table.TableExport;
import net.fichotheque.exportation.table.TableExportContext;
import net.fichotheque.extraction.ExtractionContext;
import net.fichotheque.permission.PermissionSummary;
import net.fichotheque.selection.SelectionDef;
import net.fichotheque.tools.exportation.table.TableExportOdsParameters;
import net.mapeadores.util.io.StreamProducer;
import net.mapeadores.util.logging.ErrorMessageException;
import net.mapeadores.util.request.RequestMap;
import net.mapeadores.util.servlets.ResponseHandler;
import net.mapeadores.util.servlets.handlers.StreamResponseHandler;


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

    private final static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    private final BdfParameters bdfParameters;
    private final TableExportParameters tableExportParameters;
    private final boolean merge;
    private final boolean withThesaurusTable;
    private final SelectionDef filterSelectionDef;

    private MultiTableExportEngine(BdfParameters bdfParameters, TableExportParameters tableExportParameters, boolean merge, boolean withThesaurusTable, SelectionDef filterSelectionDef) {
        this.bdfParameters = bdfParameters;
        this.tableExportParameters = tableExportParameters;
        this.merge = merge;
        this.withThesaurusTable = withThesaurusTable;
        this.filterSelectionDef = filterSelectionDef;
    }

    public ResponseHandler run() {
        BdfServer bdfServer = bdfParameters.getBdfServer();
        String fileName = getFileName();
        TableExport tableExport = getTableExport();
        Predicate<SubsetItem> globalPredicate = getGlobalPredicate();
        TableExportContext tableExportContext = bdfServer.getTableExportContext();
        ExtractionContext extractionContext = bdfParameters.getDefaultExtractionContext();
        SumCellConverter cellConverter = BdfTableExportUtils.toCellConverter(bdfServer, extractionContext, tableExport, globalPredicate);
        TableExportOdsParameters tableExportOdsParameters = TableExportOdsParameters.init(tableExportContext, bdfParameters.getWorkingLang())
                .setSumCellConverter(cellConverter)
                .setHeaderType(tableExportParameters.getHeaderType())
                .setWithThesaurusTable(withThesaurusTable);
        StreamProducer streamProducer = TableExportOdsProducer.newMultiInstance(fileName, bdfParameters, tableExport, bdfParameters.getBdfUser().getSelectedFiches(), merge, tableExportOdsParameters);
        return StreamResponseHandler.init(streamProducer);
    }

    private Predicate<SubsetItem> getGlobalPredicate() {
        if (filterSelectionDef == null) {
            return null;
        }
        return BdfServerUtils.toPredicate(bdfParameters, filterSelectionDef.getFichothequeQueries());
    }

    private TableExport getTableExport() {
        BdfServer bdfServer = bdfParameters.getBdfServer();
        PermissionSummary permissionSummary = bdfParameters.getPermissionSummary();
        String tableExportName = tableExportParameters.getTableExportName();
        if (tableExportName == null) {
            return BdfTableExportUtils.toDefaultTableExport(bdfServer, tableExportParameters.getDefaulFicheTableParameters(), permissionSummary);
        } else {
            return bdfServer.getTableExportManager().getTableExport(tableExportName);
        }
    }

    private String getFileName() {
        BdfServer bdfServer = bdfParameters.getBdfServer();
        StringBuilder buf = new StringBuilder();
        buf.append("tableexport-");
        buf.append(bdfServer.getFichotheque().getFichothequeMetadata().getBaseName());
        String tableExportName = tableExportParameters.getTableExportName();
        if (tableExportName != null) {
            if (bdfServer.getTableExportManager().containsTableExport(tableExportName)) {
                buf.append("-");
                buf.append(tableExportName);
            } else {
                tableExportName = null;
            }
        }

        buf.append(".");
        buf.append(dateFormat.format(new Date()));
        buf.append(".ods");
        return buf.toString();
    }

    public static MultiTableExportEngine buildFromRequest(BdfParameters bdfParameters, RequestMap requestMap) throws ErrorMessageException {
        RequestHandler requestHandler = RequestHandler.init(bdfParameters, requestMap).enableStore();
        TableExportParameters tableExportParameters = getTableExportParameters(requestHandler);
        boolean merge = requestHandler.isTrue(GetConstants.MERGE_PARAMNAME);
        boolean withThesaurusTable = requestHandler.isTrue(GetConstants.THESAURUSTABLE_PARAMNAME);
        SelectionDef filterSelectionDef = null;
        String selectionParamName = requestHandler.getTrimedParameter(InteractionConstants.SELECTION_PARAMNAME);
        if (!selectionParamName.isEmpty()) {
            filterSelectionDef = requestHandler.getMandatorySelectionDef();
        }
        requestHandler.store("form_tableexport");
        return new MultiTableExportEngine(bdfParameters, tableExportParameters, merge, withThesaurusTable, filterSelectionDef);
    }

    private static TableExportParameters getTableExportParameters(RequestHandler requestHandler) throws ErrorMessageException {
        TableExportParametersBuilder tableExportParametersBuilder = TableExportParametersBuilder.init()
                .setFicheTableParameters(requestHandler.getFicheTableParameters())
                .setHeaderType(requestHandler.getHeaderType());
        String defaultExportParam = requestHandler.getTrimedParameter(GetConstants.DEFAULTEXPORT_PARAMNAME);
        if (defaultExportParam.equals("0")) {
            String tableExportName = requestHandler.getTrimedParameter(InteractionConstants.TABLEEXPORT_PARAMNAME);
            if (!tableExportName.isEmpty()) {
                boolean present = requestHandler.getBdfServer().getTableExportManager().containsTableExport(tableExportName);
                if (!present) {
                    throw BdfErrors.unknownParameterValue(InteractionConstants.TABLEEXPORT_PARAMNAME, tableExportName);
                }
                tableExportParametersBuilder.setTableExportName(tableExportName);
            }
        }
        return tableExportParametersBuilder.toTableExportParameters();
    }

}
