/* BdfServer - Copyright (c) 2020 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.uml;

import fr.exemole.bdfserver.api.BdfServer;
import fr.exemole.bdfserver.api.storage.BdfStorageException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import net.mapeadores.util.io.FileUtils;
import net.mapeadores.util.text.RelativePath;
import net.mapeadores.util.uml.PumlUtils;
import fr.exemole.bdfserver.api.storage.StorageRoot;


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

    private final BdfServer bdfServer;
    private final StorageRoot cacheStorage;

    public DiagramCache(BdfServer bdfServer) {
        this.bdfServer = bdfServer;
        this.cacheStorage = bdfServer.getCacheStorage();
    }

    public File getFile(String name, String pumlEncoded, String extension) {
        try {
            CacheEntry cacheEntry = new CacheEntry(name, pumlEncoded);
            return cacheEntry.getFile(extension);
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }


    private class CacheEntry {

        private final String name;
        private final File entryDir;
        private final File codeFile;
        private final String pumlEncoded;
        private final boolean useCache;

        private CacheEntry(String name, String pumlEncoded) throws IOException {
            this.name = name;
            this.entryDir = cacheStorage.getFile(RelativePath.build("diagrams/" + name));
            if (!entryDir.exists()) {
                entryDir.mkdirs();
            }
            this.codeFile = new File(entryDir, "code");
            this.pumlEncoded = pumlEncoded;
            this.useCache = checkUseCache();
        }

        public File getFile(String extension) throws IOException {
            File cacheFile = new File(entryDir, "diagram." + extension);
            if ((!useCache) || (!cacheFile.exists())) {
                try (OutputStream os = new FileOutputStream(cacheFile)) {
                    PumlUtils.download(pumlEncoded, extension, os);
                }
            }
            return cacheFile;
        }

        private boolean checkUseCache() throws IOException {
            if (!codeFile.exists()) {
                saveCode();
                return false;
            }
            String currentCode = FileUtils.readFileToString(codeFile, "UTF-8");
            if (currentCode.equals(pumlEncoded)) {
                return true;
            } else {
                saveCode();
                return false;
            }
        }

        private void saveCode() throws IOException {
            FileUtils.cleanDirectory(entryDir);
            FileUtils.writeStringToFile(codeFile, pumlEncoded, "UTF-8");
        }

    }


}
