package uk.ac.reload.diva.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.zip.ZipEntry;

/**
 *
 * @author Gonzalo
 */
public class CopyTaskJWS {

    private File target;
    private ZipEntry zipEntry;
    private FileOutputStream out;
    private byte[] data;
    private int len;
    private boolean exists;
    private File destinationFolder;
    private URL resourceUrl;

    /**
     * Constructor
     * @param resource the path to the jar file (local) or the path of a resource within the jar (webstart)
     * @param destinationFolder File representing the destination folder where the resources are extracted;
     *        the dest is created if required
     */
    public CopyTaskJWS(String resource, File destinationFolder) throws IOException {
        this.destinationFolder = destinationFolder;

        // resources can be in one of two places:
        // if in the working dir (ie $build/reload.jar)
        // webstart/jar in classpath - specify something inside this jar
        ClassLoader classLoader = this.getClass().getClassLoader();
        resourceUrl = classLoader.getResource(resource);
        if (resourceUrl == null) {
            throw new IOException("Resource not found: " + resource);
        } //TODO añadido por gonzalo
        else {
            System.out.println("resourceUrl: " + resourceUrl.toString());
        }
    }

    /**
     * expand the resource archive into the destination folder
     * @param overwrite
     * @throws IOException
     */
    public void execute(boolean overwrite) throws IOException {
        // we have a jar file which needs to be extracted to the home directory
        // creating de novo if necessary
        // overwriting files
        // creating necessary dirs
        // leaving existing files not in the jar alone

        // need ant to build this support jar from source

        String file = resourceUrl.getFile();
        //int start = file.indexOf(':') + 1;
        int end = file.lastIndexOf('!');
        System.out.println(file);

        java.util.zip.ZipInputStream zipInputStream = new java.util.zip.ZipInputStream(new URL(file.substring(0, end)).openStream());
        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
            //System.out.println("Procesando " + zipEntry.getName() + " del jar");
            //System.out.println(zipEntry.getName());
            //TODO copiar cada entrada del JAR a una carpeta local para que el ReloadTotal pueda acceder a los archivos
            //Fichero que vamos a extraer/directorio que vamos a crear
            target = new File(destinationFolder, zipEntry.getName());

            exists = target.exists();

            // is a problem if the user made a file with the same name of a dir we're trying to create
            if (zipEntry.getSize() == 0) { // folder doesn't exist
                if (!target.mkdirs()) {
                    // already exists (or some other problem but that will throw)
                    // check to make sure there isn't a file of the same name
                    if (target.isFile()) {
                        StringBuffer newName = new StringBuffer(target.getName());
                        newName.append('~');
                        File parentFile = target.getParentFile();
                        File newTarget = new File(parentFile, newName.toString());
                        while (newTarget.exists()) {
                            newName.append('~');
                            newTarget = new File(parentFile, newName.toString());
                        }
                        target.renameTo(newTarget);
                    }
                }
                continue;
            } else {
                // sometimes we have a file and it's parent folder isn't made
                File parentFile = target.getParentFile();
                parentFile.mkdirs();
            }

            if (overwrite && exists) {
                // any way to check to see if the files are the same instead?
//                System.out.println("zipEntry.getSize() = " + zipEntry.getSize());
//                System.out.println("zipEntry.getTime() = " + zipEntry.getTime());
//                System.out.println("target.lastModified() = " + target.lastModified());
//                System.out.println("target.length() = " + target.length());
                target.delete();
                exists = false;
            }

            if (!exists) {
                out = new FileOutputStream(target);
                data = new byte[10240];
                while (zipInputStream.available() != 0) {
                    len = zipInputStream.read(data);
                    //System.out.println("leidos " + len + " bytes de " + zipEntry.getName() + " " + zipInputStream.available());
                    if (len < 1) {
                        break;
                    }
                    out.write(data, 0, len);
                }
                
                out.close();
            }
        }
    }
}
