/* BdfServer - Copyright (c) 2006-2024 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.BalayageUnitRunner;
import fr.exemole.bdfserver.api.externalscript.ExternalScript;
import fr.exemole.bdfserver.tools.balayage.engine.runners.RunnerFactory;
import fr.exemole.bdfserver.tools.runners.ScrutariExportRunner;
import fr.exemole.bdfserver.tools.runners.SqlExportRunner;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.fichotheque.exportation.balayage.BalayageMode;
import net.fichotheque.exportation.balayage.BalayagePostscriptum;
import net.fichotheque.exportation.balayage.BalayageUnit;
import net.fichotheque.exportation.scrutari.ScrutariExportDef;
import net.fichotheque.exportation.sql.SqlExportDef;
import net.mapeadores.util.logging.CommandMessage;


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

    private final BalayageParameters balayageParameters;
    private final List<BalayageUnitRunner> balayageUnitRunnerList = new ArrayList<BalayageUnitRunner>();
    private final SiteMapBuilder siteMapBuilder;

    public BalayageEngine(BalayageParameters balayageParameters) {
        this.balayageParameters = balayageParameters;
        this.siteMapBuilder = (SiteMapBuilder) balayageParameters.getFileGenerationListener();
        List<BalayageUnit> balayageUnitList = balayageParameters.getBalayageDef().getBalayageUnitList();
        int balayageUnitLength = balayageUnitList.size();
        for (int i = 0; i < balayageUnitLength; i++) {
            BalayageUnit balayageUnit = balayageUnitList.get(i);
            if (doBalayageUnit(balayageUnit)) {
                BalayageUnitRunner bu = RunnerFactory.get(balayageParameters, i, balayageUnit);
                balayageUnitRunnerList.add(bu);
            }
        }
    }

    private boolean doBalayageUnit(BalayageUnit balayageUnit) {
        BalayageMode balayageMode = balayageParameters.getBalayageMode();
        if (balayageMode == null) {
            return true;
        }
        return balayageUnit.hasMode(balayageMode.getName());
    }

    public void run() {
        BalayageLog balayageLog = balayageParameters.getBalayageLog();
        balayageLog.runStarted();
        for (BalayageUnitRunner bu : balayageUnitRunnerList) {
            bu.run();
            bu.dispose();
        }
        balayageUnitRunnerList.clear();
        if (siteMapBuilder != null) {
            try {
                String path = siteMapBuilder.writeSiteMapFile(balayageParameters.getBalayageRootDirectory());
                balayageLog.addPostscriptumLog(BalayageLog.SITEMAP_KEY, path);
            } catch (IOException ioe) {
                balayageLog.addPostscriptumError(BalayageLog.SITEMAP_KEY, "", BalayageLog.IO_EXCEPTION, getMessage(ioe));
            }
        }
        execPostscriptum();
        balayageLog.runEnded();
    }

    private void execPostscriptum() {
        BalayageLog balayageLog = balayageParameters.getBalayageLog();
        if (balayageLog.hasError()) {
            return;
        }
        BdfServer bdfServer = balayageParameters.getBdfServer();
        BalayagePostscriptum postscriptum = balayageParameters.getBalayageDef().getPostscriptum();
        for (String name : postscriptum.getScrutariExportNameList()) {
            ScrutariExportDef scrutariExportDef = bdfServer.getScrutariExportManager().getScrutariExportDef(name);
            if (scrutariExportDef != null) {
                try {
                    ScrutariExportRunner.run(scrutariExportDef, bdfServer, balayageParameters.getPathConfiguration());
                    balayageLog.addPostscriptumLog(BalayageLog.SCRUTARIEXPORT_KEY, name);
                } catch (IOException ioe) {
                    balayageLog.addPostscriptumError(BalayageLog.SCRUTARIEXPORT_KEY, name, BalayageLog.IO_EXCEPTION, getMessage(ioe));
                }
            } else {
                balayageLog.addPostscriptumError(BalayageLog.SCRUTARIEXPORT_KEY, name, BalayageLog.UNKNOWN_NAME, name);
            }
        }
        for (String name : postscriptum.getSqlExportNameList()) {
            SqlExportDef sqlExportDef = bdfServer.getSqlExportManager().getSqlExportDef(name);
            if (sqlExportDef != null) {
                try {
                    CommandMessage message = SqlExportRunner.run(sqlExportDef, bdfServer, balayageParameters.getPathConfiguration(), false);
                    if (message.isErrorMessage()) {
                        balayageLog.addPostscriptumError(BalayageLog.SQLEXPORT_KEY, name, BalayageLog.SQLEXPORT_ERROR, message.getMessageKey());
                    } else {
                        balayageLog.addPostscriptumLog(BalayageLog.SQLEXPORT_KEY, name);
                    }
                } catch (IOException ioe) {
                    balayageLog.addPostscriptumError(BalayageLog.SQLEXPORT_KEY, name, BalayageLog.IO_EXCEPTION, getMessage(ioe));
                }
            } else {
                balayageLog.addPostscriptumError(BalayageLog.SQLEXPORT_KEY, name, BalayageLog.UNKNOWN_NAME, name);
            }
        }
        if (balayageLog.hasError()) {
            return;
        }
        for (String name : postscriptum.getExternalScriptNameList()) {
            ExternalScript externalScript = bdfServer.getExternalScriptManager().getExternalScript(name);
            if (externalScript != null) {
                try {
                    externalScript.exec();
                    balayageLog.addPostscriptumLog(BalayageLog.COMMAND_KEY, name);
                } catch (IOException ioe) {
                    balayageLog.addPostscriptumError(BalayageLog.COMMAND_KEY, name, BalayageLog.COMMANDIO_EXCEPTION, getMessage(ioe));
                }
            } else {
                balayageLog.addPostscriptumError(BalayageLog.COMMAND_KEY, name, BalayageLog.COMMANDCHECK_EXCEPTION, "wrong script name : " + name);
            }
        }
    }

    private String getMessage(IOException ioe) {
        String msg = ioe.getMessage();
        String message = ioe.getClass().getName();
        if (msg != null) {
            message = message + " : " + msg;
        }
        return message;
    }

}
