/* BdfServer - Copyright (c) 2018-2023 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.conf.dom;

import fr.exemole.bdfserver.conf.ConfConstants;
import fr.exemole.bdfserver.conf.ConfUtils;
import fr.exemole.bdfserver.conf.WebappDirs;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import net.mapeadores.util.exceptions.InitException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


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

    private final String servletContextName;
    private final File relativeDirectory;
    private File etcDirectory;
    private File varDirectory;

    public ConfDOMReader(String servletContextName, File relativeDirectory) {
        this.servletContextName = servletContextName;
        this.relativeDirectory = relativeDirectory;
    }

    public WebappDirs readConf(Element element_xml, boolean multiBdf) {
        Map<String, File> customDirMap = new HashMap<String, File>();
        customDirMap.put(ConfConstants.LIB_EXTENSIONS, new File(relativeDirectory, "WEB-INF" + File.separator + "extensions"));
        NodeList nodeList = element_xml.getChildNodes();
        int nodeLength = nodeList.getLength();
        for (int i = 0; i < nodeLength; i++) {
            Node nd = nodeList.item(i);
            if (nd instanceof Element) {
                Element el = (Element) nd;
                String tagName = el.getTagName();
                if (tagName.equals("etc-dir")) {
                    etcDirectory = readMainDirectory(el);
                } else if (tagName.equals("var-dir")) {
                    varDirectory = readMainDirectory(el);
                }
            }
        }
        if (etcDirectory == null) {
            throw new InitException("Missing <etc-dir> element in bdfConfFile");
        }
        if (varDirectory == null) {
            throw new InitException("Missing <var-dir> element in bdfConfFile");
        }
        for (int i = 0; i < nodeLength; i++) {
            Node nd = nodeList.item(i);
            if (nd instanceof Element) {
                Element el = (Element) nd;
                String tagName = el.getTagName();
                if (tagName.equals("dir")) {
                    String dirKey = el.getAttribute("key");
                    String path = el.getAttribute("path");
                    if ((dirKey.length() > 0) && (path.length() > 0)) {
                        File directory = new File(path);
                        if (!directory.isAbsolute()) {
                            directory = new File(getRelativeDirectory(dirKey), path);
                        }
                        if (appendServletContext(el)) {
                            directory = new File(directory, servletContextName);
                        }
                        customDirMap.put(dirKey, directory);
                    }
                }
            }
        }
        WebappDirs webappDirs = WebappDirs.build(multiBdf, etcDirectory, varDirectory, customDirMap);
        if (!multiBdf) {
            File iniFile = ConfUtils.getMultiIniFile(webappDirs);
            if ((iniFile.exists()) && (!iniFile.isDirectory())) {
                webappDirs = WebappDirs.build(true, etcDirectory, varDirectory, customDirMap);
            }
        }
        return webappDirs;
    }

    private File readMainDirectory(Element el) {
        String path = el.getAttribute("path");
        if (path.length() == 0) {
            return null;
        }
        File directory = new File(path);
        if (!directory.isAbsolute()) {
            directory = new File(relativeDirectory, path);
        }
        if (appendServletContext(el)) {
            directory = new File(directory, servletContextName);
        }
        return directory;
    }

    private boolean appendServletContext(Element el) {
        String appendContextString = el.getAttribute("append-context").toLowerCase();
        boolean appendContext = false;
        if ((appendContextString.equals("true"))) {
            appendContext = true;
        }
        return appendContext;
    }

    private File getRelativeDirectory(String dirKey) {
        if (dirKey.startsWith("var.")) {
            return varDirectory;
        }
        if (dirKey.startsWith("etc.")) {
            return etcDirectory;
        }
        return relativeDirectory;
    }

}
