package sikd.sikd5.sikd5service.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.model.FileHeader;

/**
 *
 * @author sora
 */
public class UnzipFileService {

    String OUTPUT_FOLDER = "";
    private final int BUFF_SIZE = 4096;

    /**
     * method unZipIt
     *
     * @param zipFile
     * @param outputFolder
     * @param jenisFile
     * @return String
     * @throws Exception
     */
    public String unZipIt_lama(String zipFile, String outputFolder, String jenisFile) throws Exception {
        byte[] buffer = new byte[1024];
//     try{    		
        //create output directory is not exists
        File folder = new File(OUTPUT_FOLDER);
        if (!folder.exists()) {
            folder.mkdir();
        }

        //get the zip file content
        ZipInputStream zis
           = new ZipInputStream(new FileInputStream(zipFile));
        //get the zipped file list entry
        ZipEntry ze = zis.getNextEntry();
        String fileName = "";

        if (ze != null) {
            fileName = ze.getName();
            if (!fileName.trim().endsWith(jenisFile.trim()))
                throw new Exception("Jenis Berkas Yang Terdapat Di Dalam Berkas zip Tidak Sesuai Dengan Permintaan (" + jenisFile + ")");

            File newFile = new File(outputFolder + File.separator + fileName);

            System.out.println("file unzip : " + newFile.getAbsoluteFile());

            //create all non exists folders
            //else you will hit FileNotFoundException for compressed folder
            new File(newFile.getParent()).mkdirs();

            FileOutputStream fos = new FileOutputStream(newFile);

            int len;
            while ((len = zis.read(buffer)) > 0) {
                fos.write(buffer, 0, len);
            }

            fos.close();
//            ze = zis.getNextEntry();
        }

        zis.closeEntry();
        zis.close();

        System.out.println("Done");
        return fileName;

//    }catch(IOException ex){
//       ex.printStackTrace(); 
//    }
    }

    public String unZipIt1(String zipFile, String outputFile, String jenisFile, String strpwd) throws Exception {
        String fileName = "";
        net.lingala.zip4j.io.ZipInputStream is = null;
        OutputStream os = null;

        // Initiate the ZipFile
        ZipFile zipFile1 = new ZipFile(zipFile);
//        String destinationPath = "c:\\ZipTest";

        // If zip file is password protected then set the password
        if (zipFile1.isEncrypted()) {
            zipFile1.setPassword(strpwd);
        }
        List fileHeaderList = zipFile1.getFileHeaders();

        // Loop through all the fileHeaders
        FileHeader fileHeadernya = null;
        for (int i = 0; i < fileHeaderList.size(); i++) {
            FileHeader fileHeader = (FileHeader) fileHeaderList.get(i);
            if (fileHeader != null) {
                //Build the output file
                String filename = fileHeader.getFileName();
                if (filename != null & !filename.equals("")) {
                    if (filename.trim().toLowerCase().endsWith(jenisFile.trim().toLowerCase())) {
                        fileName = filename;
                        fileHeadernya = fileHeader;
                    }
                }

            }
        }
        if (fileName.equals("")) {
            throw new Exception("Jenis Berkas Yang Terdapat Di Dalam Berkas zip Tidak Ada Sesuai Dengan Permintaan (" + jenisFile + ")");
        }
//        File newFile = new File(outputFolder + File.separator + fileName);
        File newFile = new File(outputFile);
//        System.out.println("file unzip : " + newFile.getAbsoluteFile());
        //Check if the directories(including parent directories)
        //in the output file path exists
        File parentDir = newFile.getParentFile();
        if (!parentDir.exists()) {
            parentDir.mkdirs();
        }

        //Get the InputStream from the ZipFile
        is = zipFile1.getInputStream(fileHeadernya);
        //Initialize the output stream
        os = new FileOutputStream(newFile);

        int readLen = -1;
        byte[] buff = new byte[BUFF_SIZE];

        //Loop until End of File and write the contents to the output stream
        while ((readLen = is.read(buff)) != -1) {
            os.write(buff, 0, readLen);
        }

        //Please have a look into this method for some important comments
        closeFileHandlers(is, os);

        return fileName;
    }

    /**
     * method unZipIt
     *
     * @param zipFile
     * @param outputFolder
     */
    public void unZipIt(String zipFile, String outputFolder) {
        byte[] buffer = new byte[1024];
        try {

            //create output directory is not exists
            File folder = new File(OUTPUT_FOLDER);
            if (!folder.exists()) {
                folder.mkdir();
            }

            //get the zip file content
            ZipInputStream zis
               = new ZipInputStream(new FileInputStream(zipFile));
            //get the zipped file list entry
            ZipEntry ze = zis.getNextEntry();

            while (ze != null) {

                String fileName = ze.getName();
                File newFile = new File(outputFolder + File.separator + fileName);

                System.out.println("file unzip : " + newFile.getAbsoluteFile());

                //create all non exists folders
                //else you will hit FileNotFoundException for compressed folder
                new File(newFile.getParent()).mkdirs();

                FileOutputStream fos = new FileOutputStream(newFile);

                int len;
                while ((len = zis.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }

                fos.close();
                ze = zis.getNextEntry();
            }

            zis.closeEntry();
            zis.close();

            System.out.println("Done");

        } catch (IOException ex) {
            Logger.getLogger(UnzipFileService.class.getName());

        }
    }

    private void closeFileHandlers(net.lingala.zip4j.io.ZipInputStream is, OutputStream os) throws IOException {
        //Close output stream
        if (os != null) {
            os.close();
            os = null;
        }

        //Closing inputstream also checks for CRC of the the just extracted file.
        //If CRC check has to be skipped (for ex: to cancel the unzip operation, etc)
        //use method is.close(boolean skipCRCCheck) and set the flag,
        //skipCRCCheck to false
        //NOTE: It is recommended to close outputStream first because Zip4j throws 
        //an exception if CRC check fails
        if (is != null) {
            is.close();
            is = null;
        }
    }

}
