package utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Class estatica que creara el zip que podra ser descarregat.
 */
public class ZipUtils {

    private static List<String> fileList;
    private static String SOURCE_FOLDER; // SourceFolder path

    
    public static ByteArrayOutputStream createZIP(String directory){
        fileList = new ArrayList();
        SOURCE_FOLDER = directory;
        System.out.println("    Directory: "+directory);
        System.out.println("#GenerateFileList");
        generateFileList(new File(SOURCE_FOLDER));
        System.out.println("    Found "+fileList.size()+" files");
        System.out.println("#GenerateFileList:end");
        return zipIt();
    }     

    public static ByteArrayOutputStream zipIt() {
        System.out.println("#ZipIt");
        byte[] buffer = new byte[1024];
        String source = "";
        
        ByteArrayOutputStream fos = null;
        ZipOutputStream zos = null;
        try {
            source = SOURCE_FOLDER;
            try {
                if (source.lastIndexOf(File.separator) + 1 == source.length())
                    source = source.substring(0, source.length()-1);
                
                source = source.substring(source.lastIndexOf(File.separator) + 1, source.length());
            } catch (Exception e) {
                source = SOURCE_FOLDER;
            }
            System.out.println("    root dir name: "+source);
            
            fos = new ByteArrayOutputStream();
            zos = new ZipOutputStream(fos);

            FileInputStream in = null;

            for (String file : fileList) {
                ZipEntry ze = new ZipEntry(source + File.separator + file);
                zos.putNextEntry(ze);
                
                try {
                    in = new FileInputStream(SOURCE_FOLDER + File.separator + file);
                    int len;
                    
                    while ((len = in.read(buffer)) > 0) {
                        zos.write(buffer, 0, len);
                    }
                } catch(Exception e){
                    System.out.println(e.getMessage());          
                            
                } finally {
                    in.close();
                }
            }
            zos.closeEntry();
            System.out.println("    Succesfully created");

        } catch (IOException ex) {
            System.err.println("    An error ocurred");
            ex.printStackTrace();
        } finally {
            try {
                zos.close();
            } catch (IOException e) {
                System.err.println("    An error ocurred x2");
                e.printStackTrace();
            }
        }
        System.out.println("#ZipIt:end");
        return fos;
    }
    
    
    public static void zipIt(String zipFile) {
        System.out.println("#ZipIt");
        byte[] buffer = new byte[1024];
        String source = "";
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        
        try {
            try {
                source = SOURCE_FOLDER.substring(SOURCE_FOLDER.lastIndexOf(File.separator) + 1, SOURCE_FOLDER.length());
            } catch (Exception e) {
                source = SOURCE_FOLDER;
            }
            
            fos = new FileOutputStream(zipFile);
            zos = new ZipOutputStream(fos);
            
            FileInputStream in = null;

            for (String file : fileList) {
                
                ZipEntry ze = new ZipEntry(source + File.separator + file);
                zos.putNextEntry(ze);
                try {
                    in = new FileInputStream(SOURCE_FOLDER + File.separator + file);
                    int len;
                    
                    while ((len = in.read(buffer)) > 0) {
                        zos.write(buffer, 0, len);
                        
                    }
                } finally {
                    in.close();
                }
            }

            zos.closeEntry();
            System.out.println("    Succesfully created");

        } catch (IOException ex) {
            System.err.println("    An error ocurred");
            ex.printStackTrace();
        } finally {
            try {
                zos.close();
            } catch (IOException e) {
                System.err.println("    An error ocurred x2");
                e.printStackTrace();
            }
        }
        System.out.println("#ZipIt:end");
    }
    
    public static void saveArray (ByteArrayOutputStream baos, String filename){
        System.out.println("#SaveArray");
        OutputStream os = null;
        try {
            os = new FileOutputStream(filename);
            baos.writeTo(os);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ZipUtils.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ZipUtils.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                os.close();
            } catch (IOException ex) {
                Logger.getLogger(ZipUtils.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        System.out.println("#SaveArray:end");
    }
    
    public static void generateFileList(File node) {
        // add file only
        if (node.isFile()) {
            fileList.add(generateZipEntry(node.toString()));
        }

        if (node.isDirectory()) {
            String[] subNote = node.list();
            
            for (String filename : subNote) {
                generateFileList(new File(node, filename));
            }
        }
    }

    private static String generateZipEntry(String file) {
        if (SOURCE_FOLDER.lastIndexOf(File.separator)==(SOURCE_FOLDER.length()-1)){
            return file.substring(SOURCE_FOLDER.length(), file.length());
        }
        return file.substring(SOURCE_FOLDER.length()+1, file.length());
    }
    
    
 
}
