/* BdfServer - Copyright (c) 2010-2024 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.balayage.engine.runners;

import fr.exemole.bdfserver.tools.balayage.engine.BalayageLog;
import fr.exemole.bdfserver.tools.balayage.engine.BalayageParameters;
import fr.exemole.bdfserver.tools.balayage.engine.EngineUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import net.fichotheque.album.Album;
import net.fichotheque.album.AlbumConstants;
import net.fichotheque.album.Illustration;
import net.fichotheque.album.metadata.AlbumDim;
import net.fichotheque.exportation.balayage.BalayageConstants;
import net.fichotheque.utils.AlbumUtils;
import net.fichotheque.utils.BalayageUtils;
import net.mapeadores.util.io.IOUtils;
import net.mapeadores.util.text.AccoladeArgument;
import net.mapeadores.util.text.AccoladePattern;
import net.mapeadores.util.text.ValueResolver;
import net.fichotheque.exportation.balayage.BalayageOutput;


/**
 *
 * @author Vincent Calame
 */
public class IllustrationOutputRunner extends AbstractOutputRunner {

    private final static short NOSPECIALDIM = 0;
    private final AccoladePattern pattern;

    public IllustrationOutputRunner(BalayageParameters balayageParameters, int outputIndex, BalayageOutput output, int balayageUnitIndex) {
        super(balayageParameters, outputIndex, output, balayageUnitIndex);
        pattern = BalayageUtils.getPattern(output, BalayageConstants.ILLUSTRATION_TYPE);
    }

    public void copy(Album album, List<String> albumDimNameList, long startTime) {
        if (albumDimNameList.isEmpty()) {
            copyFiles(album, null, AlbumConstants.ORIGINAL_SPECIALDIM);
        } else {
            for (String albumDimName : albumDimNameList) {
                if (albumDimName.equals(AlbumConstants.MINI_DIMNAME)) {
                    copyFiles(album, null, AlbumConstants.MINI_SPECIALDIM);
                } else {
                    AlbumDim albumDim = album.getAlbumMetadata().getAlbumDimByName(albumDimName);
                    if (albumDim != null) {
                        copyFiles(album, albumDim, NOSPECIALDIM);
                    }
                }
            }
        }
    }

    private void copyFiles(Album album, AlbumDim albumDim, short specialDim) {
        IllustrationValueResolver valueResolver = new IllustrationValueResolver(album, albumDim, specialDim);
        File directory = rootDirectory;
        String path = EngineUtils.getPath(output, valueResolver);
        if (path != null) {
            directory = new File(directory, path);
        }
        prepareDirectory(directory);
        for (Illustration illustration : album.getIllustrationList()) {
            valueResolver.setIllustration(illustration);
            String fileName = pattern.format(valueResolver) + "." + illustration.getFormatTypeString();
            File destination = new File(directory, fileName);
            InputStream inputStream;
            if (albumDim != null) {
                inputStream = illustration.getInputStream(albumDim);
            } else {
                inputStream = illustration.getInputStream(specialDim);
            }
            try (InputStream is = inputStream; OutputStream os = new FileOutputStream(destination)) {
                IOUtils.copy(is, os);
                balayageLog.addFileGeneration(balayageUnitIndex, outputIndex, destination);
            } catch (IOException ioe) {
                String msg = ioe.getMessage();
                String message = ioe.getClass().getName();
                if (msg != null) {
                    message = message + " : " + msg;
                }
                balayageLog.addOutputError(balayageUnitIndex, outputIndex, output, BalayageLog.IO_EXCEPTION, destination.getName(), message);
            }
        }
    }


    private static class IllustrationValueResolver implements ValueResolver {

        private final Album album;
        private final AlbumDim albumDim;
        private final short specialDim;
        private Illustration illustration;

        private IllustrationValueResolver(Album album, AlbumDim albumDim, short specialDim) {
            this.album = album;
            this.albumDim = albumDim;
            this.specialDim = specialDim;
        }

        @Override
        public String getValue(AccoladeArgument patternArgument) {
            String patternArgumentName = patternArgument.getName();
            if (patternArgumentName.equals("album")) {
                return album.getSubsetName();
            }
            if (patternArgumentName.equals("albumdim")) {
                if (albumDim == null) {
                    return AlbumUtils.specialDimToString(specialDim);
                } else {
                    return albumDim.getName();
                }
            }
            if ((patternArgumentName.equals("id")) || (patternArgumentName.equals("idalbum"))) {
                if (illustration != null) {
                    return String.valueOf(illustration.getId());
                }
            }
            return AccoladePattern.toString(patternArgument);
        }

        private void setIllustration(Illustration illustration) {
            this.illustration = illustration;
        }

    }

}
