/* BdfServer - Copyright (c) 2013-2025 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.storage;

import fr.exemole.bdfserver.api.storage.EditableResourceStorage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import net.fichotheque.EditOrigin;
import net.mapeadores.util.io.DirectoryResourceStorage;
import net.mapeadores.util.io.IOUtils;
import net.mapeadores.util.io.ResourceUtils;
import net.mapeadores.util.text.RelativePath;


/**
 *
 * @author Vincent Calame
 */
public class DirectoryEditableResourceStorage extends DirectoryResourceStorage implements EditableResourceStorage {

    private final File backupDirectory;

    public DirectoryEditableResourceStorage(String name, File rootDirectory, File backupDirectory) {
        super(name, rootDirectory);
        this.backupDirectory = backupDirectory;
    }

    @Override
    public void saveResource(RelativePath path, InputStream inputStream, EditOrigin editOrigin) throws IOException {
        File file = getFile(path.toString(), true);
        if (file == null) {
            return;
        }
        if (!ResourceUtils.isValidResourceRelativePath(path)) {
            throw new IllegalArgumentException("wrong path (too short or with illegal characters): " + path);
        }
        File backupFile = getBackupFile(path.toString());
        if (backupFile != null) {
            StorageUtils.archive(file, backupFile, editOrigin);
        }
        file.getParentFile().mkdirs();
        try (OutputStream os = new FileOutputStream(file)) {
            IOUtils.copy(inputStream, os);
        }
    }

    @Override
    public boolean removeResource(RelativePath path, EditOrigin editOrigin) {
        File file = getFile(path.toString(), false);
        if (file == null) {
            return false;
        }
        if (!ResourceUtils.isValidResourceRelativePath(path)) {
            throw new IllegalArgumentException("wrong characters in path: " + path);
        }
        file.delete();
        String[] array = path.toArray();
        int pathLength = array.length - 1;
        for (int i = pathLength; i > 0; i--) {
            StringBuilder pathBuf = new StringBuilder();
            for (int j = 0; j < pathLength; j++) {
                pathBuf.append(array[j]);
                pathBuf.append('/');
            }
            File dir = new File(rootDirectory, pathBuf.toString());
            if (dir.listFiles().length > 0) {
                break;
            } else {
                dir.delete();
                pathLength--;
            }
        }
        return true;
    }

    @Override
    public boolean createFolder(RelativePath path) {
        File dir = new File(rootDirectory, path.toString());
        if (dir.exists()) {
            return false;
        }
        String[] array = path.toArray();
        for (String name : array) {
            if (!ResourceUtils.isValidFolderName(name)) {
                return false;
            }
        }
        dir.mkdirs();
        return true;
    }

    private File getBackupFile(String normalizedPath) {
        if (backupDirectory == null) {
            return null;
        }
        return new File(backupDirectory, normalizedPath);
    }


}
