/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package packagehandling;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 *
 * @author Esta
 */
public class ZipExtractor {

    public static boolean doUnPack(File archive, File toDir) throws FileNotFoundException, IOException {
        if (toDir == null || archive == null) {
            return false;
        }
        if (archive.exists() && toDir.exists()) {
            if (archive.canRead() && toDir.canWrite()) {
                return ZipExtractor.unPack(archive, toDir);
            } else if (toDir.canWrite()) {
                throw new IOException("CANT_READ_ARCHIVE");
            } else {
                throw new IOException("CANT_WRITE_DIR");
            }
        } else if (archive.exists()) {
            toDir.mkdirs();
            if (archive.canRead() && toDir.canWrite()) {
                return ZipExtractor.unPack(archive, toDir);
            } else if (toDir.canWrite()) {
                throw new IOException("CANT_READ_ARCHIVE");
            } else {
                throw new IOException("CANT_WRITE_DIR");
            }
        } else {
            throw new FileNotFoundException("ARCHIVE_NOT_FOUND");
        }
    }

    private static boolean unPack(File archive, File toDir) throws FileNotFoundException, IOException {
        ZipInputStream zip = new ZipInputStream(new FileInputStream(archive));
        ZipEntry entry = null;
        byte[] buf = new byte[1024];
        try {
            entry = zip.getNextEntry();
            while (entry != null) {
                String entryName = entry.getName();
                int n;
                FileOutputStream fos;
                File outFile = new File(entryName);
                String directory = outFile.getParent();
                if (entryName.contains("/")) {
                    File dir = new File(toDir.getAbsolutePath() + File.separator + entryName.substring(0, entryName.lastIndexOf('/')));
                    dir.mkdirs();
                    dir.setWritable(true);

                    //System.out.println(toDir.getAbsolutePath() + File.separator + entryName);
                }
                if (directory == null) {
                    if (outFile.isDirectory()) {
                        //break;
                    }
                }
                fos = new FileOutputStream(toDir.getAbsolutePath() + File.separator + entryName);
                //System.out.println(toDir.getAbsolutePath() + File.separator + entryName);
                while ((n = zip.read(buf, 0, 1024)) > -1) {
                    fos.write(buf, 0, n);
                }
                fos.close();

                zip.closeEntry();
                entry = zip.getNextEntry();
            }
            zip.close();
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
            throw new IOException("CORRUPTED_FILE");
        }
        return true;
    }
}
