package com.sysu.admin.utils.file;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * 压缩和解压 ZIP文件
 */
public class Snippet {
	
	/**
     * 压缩成ZIP 
     * @param srcFiles 需要压缩的文件列表
     * @param zipFile  目标文件
     * @throws RuntimeException 压缩失败会抛出运行时异常
     */
    public void toZip(List<File> srcFiles , File zipFile)throws RuntimeException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null ;
        try {
            zos = new ZipOutputStream(new FileOutputStream(zipFile));
            for (File srcFile : srcFiles) {
                byte[] buf = new byte[2*1024];
                zos.putNextEntry(new ZipEntry(srcFile.getName()));
                int len;
                FileInputStream in = new FileInputStream(srcFile);
                while ((len = in.read(buf)) != -1){
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                in.close();
            }
            long end = System.currentTimeMillis();
            System.out.println("压缩完成，耗时：" + (end - start) +" ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils",e);
        }finally{
            if(zos != null){
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

	
	/**
	 * zip解压
	 * @param srcFile     zip源文件
	 * @param destDir 解压后的目标文件夹
	 * @throws RuntimeException 解压失败会抛出运行时异常
	 */
	public List<File> unZip(File srcFile, File destDir, boolean override) throws RuntimeException {
		List<File> files = null;
		long start = System.currentTimeMillis();
		// 判断源文件是否存在
		if (!srcFile.exists()) {
			throw new RuntimeException(srcFile.getPath() + "所指文件不存在");
		}
		existName = new StringBuffer(100);
		// 开始解压
		ZipFile zipFile = null;
		int len;
		byte[] buf = new byte[4096];
		try {
			Charset gbk = Charset.forName("GBK");
			zipFile = new ZipFile(srcFile, gbk);
			Enumeration<?> entries = zipFile.entries();

			files = new ArrayList<>(zipFile.size());

			while (entries.hasMoreElements()) {
				ZipEntry entry = (ZipEntry) entries.nextElement();
				if (entry.isDirectory()) {//遇到文件夹直接跳过
                    continue;
                }
				String entryName = entry.getName();
				while(true) {  //保留最后的文件名
					int index = entryName.indexOf("/");
					if(index > -1) {
						entryName = entryName.substring(index+1);
					}else {
						break;
					}
				}
				
				File targetFile = new File(destDir, entryName);
				if(override == false){//当override = false 需要检查文件是否存在
					if(targetFile.exists()) {//如果存在 则跳过
						existName.append(entryName).append(",");
						continue;
					}
				}
				files.add(targetFile);
				targetFile.createNewFile();
				// 将压缩文件内容写入到这个文件中
				InputStream is = zipFile.getInputStream(entry);
				FileOutputStream fos = new FileOutputStream(targetFile);
				while ((len = is.read(buf)) != -1) {
					fos.write(buf, 0, len);
				}
				fos.flush();
				fos.close();
			}

			long end = System.currentTimeMillis();
			System.out.println(new StringBuffer("解压完成，耗时：").append((end - start)).append(" ms").toString());
		} catch (Exception e) {
			throw new RuntimeException("unzip error from ZipUtils", e);
		} finally {
			if (zipFile != null) {
				try {
					zipFile.close();
					srcFile.delete();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return files;
	}

	StringBuffer existName = null;
	public StringBuffer getExistName(){
		return existName;
	}
}
