/* BdfServer - Copyright (c) 2014-2026 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.configuration;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.configuration.LangConfiguration;
import fr.exemole.bdfserver.api.configuration.PathConfiguration;
import fr.exemole.bdfserver.api.managers.L10nManager;
import fr.exemole.bdfserver.api.storage.BdfStorageException;
import fr.exemole.bdfserver.tools.storage.StorageUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.TreeMap;
import net.fichotheque.exportation.scrutari.ScrutariExportDef;
import net.fichotheque.exportation.sql.SqlExportDef;
import net.mapeadores.util.ini.IniParser;
import net.mapeadores.util.io.DocStream;
import net.mapeadores.util.localisation.Lang;
import net.mapeadores.util.localisation.LangPreferenceBuilder;
import net.mapeadores.util.localisation.MessageLocalisation;
import net.mapeadores.util.text.RelativePath;


/**
 *
 * @author Vincent Calame
 */
public final class ConfigurationUtils {

    private final static long DELETE_TIME = 1000 * 60 * 60 * 24 * 10;
    private final static RelativePath BACKUP_PATH = RelativePath.build("backup");
    private final static RelativePath INC_PATH = RelativePath.build("balayages/_inc_");
    private final static RelativePath LOG_PATH = RelativePath.build("log");
    private final static RelativePath TMP_PATH = RelativePath.build("tmp");


    private ConfigurationUtils() {
    }

    public static void checkLangPreference(LangConfiguration langConfiguration, LangPreferenceBuilder langPreferenceBuilder) {
        langPreferenceBuilder.addLangs(langConfiguration.getWorkingLangs());
        langPreferenceBuilder.addLangs(langConfiguration.getSupplementaryLangs());
    }

    public static MessageLocalisation[] getMessageLocalisationArray(BdfServer bdfServer, Lang[] langArray) {
        L10nManager l10nManager = bdfServer.getL10nManager();
        int length = langArray.length;
        MessageLocalisation[] result = new MessageLocalisation[length];
        for (int i = 0; i < length; i++) {
            result[i] = l10nManager.getMessageLocalisation(langArray[i]);
        }
        return result;
    }

    public static File toDirectory(String system) throws FileNotFoundException {
        if (system == null) {
            return null;
        }
        system = system.trim();
        if (system.length() == 0) {
            return null;
        }
        File directory = new File(system);
        if ((!directory.exists()) || (!directory.isDirectory())) {
            throw new FileNotFoundException(system);
        }
        return directory;
    }

    public static File getBackupDirectory(BdfServer bdfServer) {
        File dir = bdfServer.getOutputStorage().getFile(BACKUP_PATH);
        dir.mkdirs();
        return dir;
    }

    public static File getBalayageIncludeDirectory(BdfServer bdfServer) {
        File dir = bdfServer.getOutputStorage().getFile(INC_PATH);
        dir.mkdirs();
        return dir;
    }

    public static File getLogDirectory(BdfServer bdfServer) {
        File dir = bdfServer.getOutputStorage().getFile(LOG_PATH);
        dir.mkdirs();
        return dir;
    }

    public static File getScriptErrorLogFile(BdfServer bdfServer, String scriptName) {
        File scriptsDir = new File(getLogDirectory(bdfServer), "scripts");
        scriptsDir.mkdirs();
        return new File(scriptsDir, scriptName + ".error.txt");
    }

    public static File getScriptResultLogFile(BdfServer bdfServer, String scriptName) {
        File scriptsDir = new File(getLogDirectory(bdfServer), "scripts");
        scriptsDir.mkdirs();
        return new File(scriptsDir, scriptName + ".result.txt");
    }

    public static File getTmpDirectory(BdfServer bdfServer) {
        return getTmpDirectory(bdfServer, false);
    }

    public static File getTmpDirectory(BdfServer bdfServer, boolean clean) {
        File dir = bdfServer.getOutputStorage().getFile(TMP_PATH);
        if (dir.exists()) {
            if (clean) {
                cleanDirectory(dir);
            }
        } else {
            dir.mkdirs();
        }
        return dir;
    }

    private static void cleanDirectory(File dir) {
        long currentTime = System.currentTimeMillis();
        for (File file : dir.listFiles()) {
            boolean toBeDeleted = ((currentTime - file.lastModified()) > DELETE_TIME);
            if (file.isDirectory()) {
                cleanDirectory(file);
                if ((file.listFiles().length == 0) && (toBeDeleted)) {
                    file.delete();
                }
            } else {
                if (toBeDeleted) {
                    file.delete();
                }
            }
        }
    }

    public static String getBackupRelativeUrl(String backupName) {
        return "output/backup/" + backupName;
    }

    public static String getLogRelativeUrl(String logName) {
        return "output/log/" + logName;
    }

    public static String getTmpRelativeUrl(String tmpName) {
        return "output/tmp/" + tmpName;
    }

    public static Target getTarget(PathConfiguration pathConfiguration, ScrutariExportDef scrutariExportDef) {
        String targetName = scrutariExportDef.getTargetName();
        if (targetName.isEmpty()) {
            targetName = PathConfiguration.PUBLIC_TARGET;
        }
        File dir = pathConfiguration.getTargetDirectory(targetName);
        if ((dir == null) || (!dir.exists())) {
            targetName = PathConfiguration.PUBLIC_TARGET;
            dir = pathConfiguration.getTargetDirectory(targetName);
        }
        if (targetName.equals(PathConfiguration.PUBLIC_TARGET)) {
            dir = new File(dir, "scrutari");
        }
        RelativePath relativePath = scrutariExportDef.getTargetPath();
        if (!relativePath.isEmpty()) {
            dir = new File(dir, relativePath.toString());
        }
        dir.mkdirs();
        String baseUrl;
        if (targetName.equals(PathConfiguration.PUBLIC_TARGET)) {
            baseUrl = getBaseUrl(pathConfiguration, "scrutari", relativePath);
        } else {
            baseUrl = null;
        }
        return new Target(dir, baseUrl);
    }

    public static Target getTarget(PathConfiguration pathConfiguration, SqlExportDef sqlExportDef) {
        String targetName = sqlExportDef.getTargetName();
        if (targetName.isEmpty()) {
            targetName = PathConfiguration.PUBLIC_TARGET;
        }
        File dir = pathConfiguration.getTargetDirectory(targetName);
        if ((dir == null) || (!dir.exists())) {
            targetName = PathConfiguration.PUBLIC_TARGET;
            dir = pathConfiguration.getTargetDirectory(targetName);
        }
        if (targetName.equals(PathConfiguration.PUBLIC_TARGET)) {
            dir = new File(dir, "sql");
        }
        RelativePath relativePath = sqlExportDef.getTargetPath();
        if (!relativePath.isEmpty()) {
            dir = new File(dir, relativePath.toString());
        }
        dir.mkdirs();
        String fileName = sqlExportDef.getFileName();
        if (fileName.isEmpty()) {
            fileName = sqlExportDef.getName() + ".sql";
        }
        String baseUrl;
        if (targetName.equals(PathConfiguration.PUBLIC_TARGET)) {
            baseUrl = getBaseUrl(pathConfiguration, "sql", relativePath) + fileName;
        } else {
            baseUrl = null;
        }
        return new Target(new File(dir, fileName), baseUrl);
    }

    private static String getBaseUrl(PathConfiguration pathConfiguration, String root, RelativePath relativePath) {
        String publicUrl;
        if (relativePath.isEmpty()) {
            publicUrl = root + "/";
        } else {
            publicUrl = root + "/" + relativePath.toString() + "/";
        }
        return pathConfiguration.getPublicUrl(publicUrl);
    }

    public static Map<String, String> getOdtLogoParameters(BdfServer bdfServer) {
        Map<String, String> logoMap = new TreeMap<String, String>();
        DocStream logoIni = bdfServer.getResourceDocStream(StorageUtils.LOGO_ODT_INI);
        if (logoIni != null) {
            try (InputStream is = logoIni.getInputStream()) {
                IniParser.parseIni(is, logoMap);
            } catch (IOException ioe) {
                throw new BdfStorageException(ioe);
            }
        }
        return logoMap;
    }

}
