/* BdfServer_HtmlProducers - Copyright (c) 2021-2022 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.htmlproducers.configuration;

import fr.exemole.bdfserver.api.BdfServerConstants;
import fr.exemole.bdfserver.api.configuration.PathConfiguration;
import fr.exemole.bdfserver.api.instruction.BdfParameters;
import fr.exemole.bdfserver.api.interaction.Domains;
import fr.exemole.bdfserver.api.interaction.InteractionConstants;
import fr.exemole.bdfserver.commands.configuration.ExternalScriptRunCommand;
import fr.exemole.bdfserver.conf.BdfServerDirs;
import fr.exemole.bdfserver.conf.ConfConstants;
import fr.exemole.bdfserver.email.SmtpManager;
import fr.exemole.bdfserver.html.BdfServerHtmlProducer;
import fr.exemole.bdfserver.html.consumers.PageUnit;
import fr.exemole.bdfserver.tools.BH;
import fr.exemole.bdfserver.tools.configuration.ConfigurationUtils;
import fr.exemole.bdfserver.tools.configuration.PathConfigurationBuilder;
import java.io.File;
import java.util.SortedSet;
import java.util.function.Consumer;
import net.mapeadores.util.html.HA;
import net.mapeadores.util.html.HtmlConstants;
import net.mapeadores.util.html.HtmlPrinter;
import net.mapeadores.util.logging.LogUtils;
import net.mapeadores.util.logging.SourceLogsBuilder;
import net.mapeadores.util.logging.SourceLogs;


/**
 *
 * @author Vincent Calame
 */
public class EtcConfigHtmlProducer extends BdfServerHtmlProducer {

    private final static Consumer<HtmlPrinter> MISSING = new Missing();

    public EtcConfigHtmlProducer(BdfParameters bdfParameters) {
        super(bdfParameters);
        addThemeCss("configuration.css");
    }

    @Override
    public void printHtml() {
        start();

        this
                .__(PageUnit.start("_ title.configuration.paths"))
                .__(printPathConfiguration())
                .__(PageUnit.END);
        this
                .__(PageUnit.start("_ title.configuration.scripts"))
                .__(printExternalScripts())
                .__(PageUnit.END);
        this
                .__(PageUnit.start("_ title.configuration.run"))
                .__(printRun())
                .__(PageUnit.END);
        this
                .__(PageUnit.start("_ title.configuration.smtp"))
                .__(printSmtp())
                .__(PageUnit.END);
        end();
    }

    private boolean printPathConfiguration() {
        SourceLogsBuilder logsBuilder = new SourceLogsBuilder();
        PathConfiguration pathConfiguration = PathConfigurationBuilder.build(bdfServer, logsBuilder);
        BdfServerDirs dirs = bdfServer.getBdfServerDirs();
        File pathsIni = dirs.getSubPath(ConfConstants.ETC_CONFIG, "paths.ini");
        File defaultPathsIni = dirs.getSubPath(ConfConstants.ETC_CONFIG_DEFAULT, "paths.ini");
        printPathInfo(pathsIni, "_ label.configuration.path_pathsini", false);
        if (!defaultPathsIni.equals(pathsIni)) {
            printPathInfo(defaultPathsIni, "_ label.configuration.path_defaultpathsini", false);
        }
        this
                .H3()
                .__localize("_ title.configuration.availablepaths")
                ._H3()
                .UL()
                .__(printLi("public_path", pathConfiguration.getPublicDirectory().getPath()))
                .__(printLi("public_url", pathConfiguration.getPublicUrl("")));
        for (String targetName : pathConfiguration.getTargetNameSet()) {
            this
                    .__(printLi("target." + targetName, pathConfiguration.getTargetDirectory(targetName).getPath()));
        }
        this
                ._UL();
        SourceLogs pathLogs = logsBuilder.toSourceLogs();
        if (!pathLogs.isEmpty()) {
            this
                    .H3()
                    .__localize("_ title.configuration.pathlog")
                    ._H3()
                    .__(LogUtils.printHtml(this, pathLogs, "global-Logs"));
        }
        return true;
    }

    private boolean printLi(String name, String value) {
        this
                .LI()
                .CODE("cm-def")
                .__escape(name)
                ._CODE()
                .__colon()
                .CODE("cm-quote")
                .__escape(value)
                ._CODE()
                ._LI();
        return true;
    }

    private boolean printExternalScripts() {
        printPathInfo(bdfServer.getBdfServerDirs().getDir(ConfConstants.ETC_SCRIPTS), "_ label.configuration.path_scripts", true);
        SortedSet<String> nameSet = bdfServer.getExternalScriptManager().getScriptNameSet();
        if (nameSet.isEmpty()) {
            this
                    .P("configuration-Info")
                    .__localize("_ info.configuration.noscript")
                    ._P();
        } else {
            this
                    .H3()
                    .__localize("_ title.configuration.availablescripts")
                    ._H3()
                    .UL();
            for (String name : nameSet) {
                this
                        .LI()
                        .A(HA
                                .href(BH.domain(Domains.CONFIGURATION).command(ExternalScriptRunCommand.COMMANDNAME).param(ExternalScriptRunCommand.NAME_PARAMNAME, name).page(InteractionConstants.MESSAGE_PAGE))
                                .target(HtmlConstants.BLANK_TARGET))
                        .__escape(name)
                        ._A()
                        .__(printLogLinks(name))
                        ._LI();
            }
            this
                    ._UL();
        }
        return true;
    }

    private boolean printRun() {
        printPathInfo(bdfServer.getBdfServerDirs().getDir(ConfConstants.VAR_RUN), "_ label.configuration.path_run", true);
        return true;
    }

    private boolean printSmtp() {
        SmtpManager smtpManager = (SmtpManager) bdfServer.getContextObject(BdfServerConstants.SMTPMANAGER_CONTEXTOBJECT);
        String iniPath = smtpManager.getIniFilePath();
        if (iniPath.isEmpty()) {
            this
                    .P("configuration-Info")
                    .__localize("_ info.configuration.nosmtpparameters")
                    ._P();
        } else {
            short iniState = smtpManager.getInitState();
            boolean missing = (iniState == SmtpManager.INIT_NOFILE);
            this
                    .P()
                    .__localize("_ label.configuration.path_smtp")
                    .__colon()
                    .__space()
                    .CODE("cm-link")
                    .__escape(iniPath)
                    ._CODE()
                    .__if(missing, MISSING)
                    ._P();
            if (iniState == SmtpManager.INIT_OK) {
                this
                        .P("configuration-Info")
                        .__localize("_ info.configuration.smtpok")
                        ._P();
            } else if (iniState != SmtpManager.INIT_NOFILE) {
                this
                        .H3()
                        .__localize("_ title.configuration.smtperrorlist")
                        ._H3()
                        .UL();
                for (String error : smtpManager.getErrorList()) {
                    this
                            .LI()
                            .__escape(error)
                            ._LI();
                }
                this
                        ._UL();

            }
        }
        return true;
    }

    private boolean printLogLinks(String name) {
        File resultFile = ConfigurationUtils.getScriptResultLogFile(bdfServer, name);
        File errorFile = ConfigurationUtils.getScriptErrorLogFile(bdfServer, name);
        boolean withResult = ((resultFile.exists()) && (resultFile.length() > 0));
        boolean withError = ((errorFile.exists()) && (errorFile.length() > 0));
        if ((!withResult) && (!withError)) {
            return false;
        }
        this
                .__space()
                .__escape("(");
        if (withResult) {
            this
                    .A(HA.href(ConfigurationUtils.getLogRelativeUrl("scripts/" + name + ".result.txt")).target(HtmlConstants.BLANK_TARGET))
                    .__escape("result.txt")
                    ._A();
        }
        if ((withResult) && (withError)) {
            this
                    .__dash();
        }
        if (withError) {
            this
                    .A(HA.href(ConfigurationUtils.getLogRelativeUrl("scripts/" + name + ".error.txt")).target(HtmlConstants.BLANK_TARGET))
                    .__escape("error.txt")
                    ._A();
        }
        this
                .__escape(")");
        return true;
    }

    private void printPathInfo(File path, String locKey, boolean isDirectory) {
        boolean missing = false;
        if (!path.exists()) {
            missing = true;
        } else if (isDirectory) {
            if (!path.isDirectory()) {
                missing = true;
            }
        } else {
            if (path.isDirectory()) {
                missing = true;
            }
        }
        this
                .P()
                .__localize(locKey)
                .__colon()
                .__space()
                .CODE("cm-link")
                .__escape(path.getAbsolutePath())
                ._CODE()
                .__if(missing, MISSING)
                ._P();
    }


    private static class Missing implements Consumer<HtmlPrinter> {

        private Missing() {

        }

        @Override
        public void accept(HtmlPrinter hp) {
            hp
                    .__space()
                    .SPAN("configuration-Warning")
                    .__escape("(")
                    .__localize("_ warning.configuration.missingpath")
                    .__escape(")")
                    ._SPAN();
        }

    }

}
