/* BdfServer_DirectoryStorage - Copyright (c) 2010-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.storage.directory.implementations;

import fr.exemole.bdfserver.api.storage.BdfStorageException;
import fr.exemole.bdfserver.storage.directory.StorageDirectory;
import fr.exemole.bdfserver.storage.directory.bdfdata.BdfdataConstants;
import fr.exemole.bdfserver.storage.directory.bdfdata.IllustrationDirectory;
import fr.exemole.bdfserver.storage.directory.bdfdata.Remove;
import fr.exemole.bdfserver.storage.directory.bdfdata.Save;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.IIOException;
import net.fichotheque.EditOrigin;
import net.fichotheque.SubsetKey;
import net.fichotheque.album.Album;
import net.fichotheque.album.AlbumConstants;
import net.fichotheque.album.Illustration;
import net.fichotheque.impl.AlbumDataSource;
import net.mapeadores.util.awt.ResizeInfo;
import net.mapeadores.util.exceptions.InternalResourceException;
import net.mapeadores.util.images.ImageResizing;
import net.mapeadores.util.io.FileUtils;
import net.mapeadores.util.logging.ErrorMessageException;


/**
 *
 * @author Vincent Calame
 */
public class AlbumDataSourceImpl implements AlbumDataSource {

    private final StorageDirectory bdfdataDirectory;
    private final File cacheDir;

    public AlbumDataSourceImpl(StorageDirectory bdfdataDirectory, File cacheDir) {
        this.bdfdataDirectory = bdfdataDirectory;
        this.cacheDir = cacheDir;
    }

    @Override
    public void saveMetadata(Album album, EditOrigin editOrigin) {
        if (editOrigin == null) {
            throw new IllegalArgumentException("editOrigin is null");
        }
        Save.saveAlbumMetadata(bdfdataDirectory, album, editOrigin);
    }

    @Override
    public void saveIllustration(Illustration illustration, EditOrigin editOrigin) {
        if (editOrigin == null) {
            throw new IllegalArgumentException("editOrigin is null");
        }
        Save.saveIllustration(bdfdataDirectory, illustration, editOrigin);
    }

    @Override
    public InputStream getInputStream(Illustration illustration, String dimName, ResizeInfo resizeInfo) {
        IllustrationDirectory imageDirectory = getIllustrationDirectory(illustration);
        if (resizeInfo == null) {
            return imageDirectory.getImage();
        }
        SubsetKey albumKey = illustration.getSubsetKey();
        String fileName = illustration.getFileName();
        File dimDir = getAlbumDirectory(albumKey, dimName);
        File dimFile = new File(dimDir, fileName);
        if (!dimFile.exists()) {
            InputStream originalInputStream = imageDirectory.getImage();
            if (originalInputStream == null) {
                return null;
            }
            try (InputStream is = originalInputStream) {
                ImageResizing.resize(is, dimFile, resizeInfo, toImageIOFormat(illustration.getFormatType()));
            } catch (IOException | ErrorMessageException e) {
                if ((e instanceof IIOException) || (e instanceof ErrorMessageException)) {
                    InputStream inputStream = this.getClass().getResourceAsStream("ecran-noir.png");
                    if (inputStream == null) {
                        throw new InternalResourceException("ecran-noir.png not found");
                    }
                    try (InputStream is2 = inputStream) {
                        ImageResizing.resize(is2, dimFile, resizeInfo, toImageIOFormat(illustration.getFormatType()));
                    } catch (IOException | ErrorMessageException e2) {
                        throw new BdfStorageException("file : " + dimFile.getAbsolutePath(), e2);
                    }
                } else {
                    throw new BdfStorageException("file : " + dimFile.getAbsolutePath(), e);
                }
            }
        }
        try {
            return new FileInputStream(dimFile);
        } catch (IOException ioe) {
            throw new BdfStorageException("file : " + dimFile.getAbsolutePath(), ioe);
        }
    }

    @Override
    public void update(Illustration illustration, InputStream inputStream) {
        IllustrationDirectory imageDirectory = getIllustrationDirectory(illustration);
        imageDirectory.updateImage(inputStream, illustration.getFormatType());
        cleanAlbumDimDirectories(illustration.getSubsetKey(), illustration.getId());
    }

    @Override
    public void clearDimCache(SubsetKey albumKey, String dimName) {
        File dimCacheDirectory = getAlbumDirectory(albumKey, dimName);
        if (dimCacheDirectory.exists()) {
            try {
                FileUtils.deleteDirectory(dimCacheDirectory);
            } catch (IOException ioe) {
                throw new BdfStorageException("dir : " + dimCacheDirectory.getAbsolutePath(), ioe);
            }
        }
    }

    @Override
    public void removeIllustration(Album album, int id, EditOrigin editOrigin) {
        cleanAlbumDimDirectories(album.getSubsetKey(), id);
        Remove.removeIllustration(bdfdataDirectory, album, id, editOrigin);
    }

    private void cleanAlbumDimDirectories(SubsetKey albumKey, int id) {
        File albumCacheDir = new File(cacheDir, albumKey.getKeyString());
        if ((albumCacheDir.exists())) {
            String baseName = albumKey.getSubsetName() + "-" + id;
            File[] files = albumCacheDir.listFiles();
            int length = files.length;
            for (int i = 0; i < length; i++) {
                File d = files[i];
                if (d.isDirectory()) {
                    File f = new File(d, baseName + ".png");
                    if (f.exists()) {
                        f.delete();
                    }
                    f = new File(d, baseName + ".jpg");
                    if (f.exists()) {
                        f.delete();
                    }
                }
            }
        }
    }

    private File getAlbumDirectory(SubsetKey albumKey, String albumDimName) {
        return getAlbumDirectory(bdfdataDirectory, cacheDir, albumKey, albumDimName);
    }

    public static File getAlbumDirectory(StorageDirectory storageDirectory, File cacheDir, SubsetKey albumKey, String albumDimName) {
        if (albumDimName == null) {
            String albumPath = BdfdataConstants.FICHOTHEQUE + File.separator + "album" + File.separator + albumKey.getSubsetName();
            return storageDirectory.getDataFile(albumPath);
        } else {
            File dimDir = new File(cacheDir, albumKey + File.separator + albumDimName);
            if (!dimDir.exists()) {
                dimDir.mkdirs();
            } else if (!dimDir.isDirectory()) {
                dimDir.delete();
                dimDir.mkdir();
            }
            return dimDir;
        }
    }

    private static String toImageIOFormat(short type) {
        switch (type) {
            case AlbumConstants.PNG_FORMATTYPE:
                return "png";
            case AlbumConstants.JPG_FORMATTYPE:
                return "jpeg";
            default:
                throw new IllegalArgumentException("unknown type " + type);
        }
    }

    private IllustrationDirectory getIllustrationDirectory(Illustration illustration) {
        return IllustrationDirectory.getIllustrationDirectory(bdfdataDirectory, illustration.getSubsetKey(), illustration.getId());
    }

}
