/* BdfServer_DirectoryStorage - Copyright (c) 2011-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.bdfdata;

import fr.exemole.bdfserver.api.storage.BdfStorageException;
import fr.exemole.bdfserver.storage.directory.StorageDirectory;
import fr.exemole.bdfserver.tools.BdfServerUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import net.fichotheque.SubsetKey;
import net.fichotheque.album.AlbumConstants;
import net.mapeadores.util.io.FileUtils;
import net.mapeadores.util.io.IOUtils;


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

    private final File dir;

    private IllustrationDirectory(File dir) {
        this.dir = dir;
    }

    public InputStream getImage() {
        File f = getImageFile();
        if (!f.exists()) {
            return null;
        }
        try {
            return new FileInputStream(f);
        } catch (IOException ioe) {
            throw new BdfStorageException("file : " + f.getAbsolutePath(), ioe);
        }
    }

    public void updateImage(InputStream inputStream, String imageType) {
        if (!dir.isDirectory()) {
            dir.delete();
        }
        dir.mkdirs();
        String extension = imageType;
        File[] fileArray = dir.listFiles();
        int length = fileArray.length;
        for (int i = 0; i < length; i++) {
            File f = fileArray[i];
            String name = f.getName();
            if (name.startsWith("img.")) {
                f.delete();
            }
        }
        String fileName = "img." + extension;
        File f = new File(dir, fileName);
        try (FileOutputStream os = new FileOutputStream(f)) {
            IOUtils.copy(inputStream, os);
        } catch (IOException ioe) {
            throw new BdfStorageException("file : " + f.getAbsolutePath(), ioe);
        }
    }

    public boolean delete() {
        try {
            if (dir.exists()) {
                FileUtils.forceDelete(dir);
                return true;
            } else {
                return false;
            }
        } catch (IOException ioe) {
            throw new BdfStorageException(ioe);
        }
    }

    private File getImageFile() {
        File f = new File(dir, "img.png");
        if (!f.exists()) {
            f = new File(dir, "img.jpg");
        }
        return f;
    }

    public static IllustrationDirectory getIllustrationDirectory(StorageDirectory bdfdataDirectory, SubsetKey subsetKey, int id) {
        File illustrationDir = bdfdataDirectory.getDataFile(getPath(subsetKey, id));
        return new IllustrationDirectory(illustrationDir);
    }

    public static String getPath(SubsetKey subsetKey, int id) {
        if (!subsetKey.isAlbumSubset()) {
            throw new IllegalArgumentException("!subsetKey.isAlbumSubset()");
        }
        if (id < 0) {
            throw new IllegalArgumentException("id < 0");
        }
        StringBuilder buf = new StringBuilder();
        buf.append(BdfdataConstants.FICHOTHEQUE);
        buf.append(File.separatorChar);
        buf.append(SubsetKey.CATEGORY_ALBUM_STRING);
        buf.append(File.separatorChar);
        buf.append(subsetKey.getSubsetName());
        buf.append(File.separatorChar);
        buf.append("i.");
        buf.append(BdfServerUtils.getMillier(id));
        buf.append(File.separatorChar);
        buf.append(id);
        return buf.toString();
    }

    public static List<IllustrationInfo> getIllustrationInfoList(StorageDirectory bdfdataDirectory, SubsetKey albumKey) {
        List<IllustrationInfo> list = new ArrayList<IllustrationInfo>();
        File imageDirectory = bdfdataDirectory.getDataFile(BdfdataConstants.FICHOTHEQUE + File.separator + SubsetKey.CATEGORY_ALBUM_STRING + File.separator + albumKey.getSubsetName());
        if ((!imageDirectory.exists()) || (!imageDirectory.isDirectory())) {
            return list;
        }
        for (File imgDir : imageDirectory.listFiles()) {
            if (!imgDir.isDirectory()) {
                continue;
            }
            String name = imgDir.getName();
            if ((name.length() < 2) || (!name.startsWith("i."))) {
                continue;
            }
            try {
                int directoryNumber = Integer.parseInt(name.substring(2));
                addIllustrationInfo(list, imgDir, directoryNumber);
            } catch (NumberFormatException nfe) {
            }
        }
        return list;
    }

    private static void addIllustrationInfo(List<IllustrationInfo> list, File intervalDirectory, int directoryNumber) {
        for (File directory : intervalDirectory.listFiles()) {
            if (!directory.isDirectory()) {
                continue;
            }
            String name = directory.getName();
            String errorMessage = null;
            try {
                int illustrationid = Integer.parseInt(name);
                if (illustrationid < 1) {
                    errorMessage = "illustrationid < 1 (directoryNumber = " + directoryNumber;
                } else if (((illustrationid < 1000) && (directoryNumber != 0)) || (illustrationid / 1000 != directoryNumber)) {
                    errorMessage = "Wrong range : illustrationid = " + illustrationid + " / directoryNumber = " + directoryNumber;
                } else {
                    IllustrationInfo illustrationInfo = getIllustrationInfo(directory, illustrationid);
                    if (illustrationInfo != null) {
                        list.add(illustrationInfo);
                    }
                }
            } catch (NumberFormatException nfe) {
            }
            if (errorMessage != null) {
                System.out.println(errorMessage);
            }
        }
    }

    private static IllustrationInfo getIllustrationInfo(File imageDir, int id) {
        File imgFile = new File(imageDir, "img.png");
        String type;
        if (imgFile.exists()) {
            type = AlbumConstants.PNG_FORMATTYPE;
        } else {
            imgFile = new File(imageDir, "img.jpg");
            if (imgFile.exists()) {
                type = AlbumConstants.JPG_FORMATTYPE;
            } else {
                return null;
            }
        }
        IllustrationInfo illustrationInfo = new IllustrationInfo(type, id, imgFile);
        return illustrationInfo;
    }


    public static class IllustrationInfo {

        private final String type;
        private final int id;
        private final File file;

        private IllustrationInfo(String type, int id, File file) {
            this.type = type;
            this.id = id;
            this.file = file;
        }

        public String getType() {
            return type;
        }

        public String getName() {
            return null;
        }

        public int getId() {
            return id;
        }

        public File getFile() {
            return file;
        }

    }

}
