package com.dxhy.common.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
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 lombok.extern.slf4j.Slf4j;

/**
 * @author peipei.li
 * @date 2019-05-08
 *
 */
@Slf4j

public class FileUtils {

    /**
     * zip解压
     *
     * @param srcFile
     *            zip源文件 /Users/peipei/Desktop/Excel/123.zip
     * @param destDirPath
     *            解压后的目标文件夹 /Users/peipei/Desktop/Excel
     *
     * @throws RuntimeException
     *             解压失败会抛出运行时异常
     */
    public static List<String> unZip(File srcFile, String destDirPath) throws RuntimeException {
        List<String> srcList = new ArrayList<>();

        // 判断源文件是否存在
        if (!srcFile.exists()) {
            throw new RuntimeException(srcFile.getPath() + "所指文件不存在");
        }
        // 开始解压
        ZipFile zipFile = null;
        try {
            Charset charset = Charset.forName("gbk");
            zipFile = new ZipFile(srcFile, charset);
            Enumeration<?> entries = zipFile.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = (ZipEntry)entries.nextElement();
                // 如果是文件夹，就创建个文件夹
                if (entry.isDirectory()) {
                    String dirPath = destDirPath + "/" + entry.getName();
                    File dir = new File(dirPath);
                    dir.mkdirs();
                } else {
                    // 如果是文件，就先创建一个文件，然后用io流把内容copy过去
                    String pathname = destDirPath + "/" + entry.getName();
                    File targetFile = new File(pathname);
                    // 保证这个文件的父文件夹必须要存在
                    if (!targetFile.getParentFile().exists()) {
                        targetFile.getParentFile().mkdirs();
                    }
                    targetFile.createNewFile();
                    // 将压缩文件内容写入到这个文件中
                    InputStream is = zipFile.getInputStream(entry);
                    FileOutputStream fos = new FileOutputStream(targetFile);
                    int len;
                    byte[] buf = new byte[1024];
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                    // 关流顺序，先打开的后关闭
                    fos.close();
                    is.close();

                    // 返回文件路径
                    srcList.add(pathname);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("unzip error from ZipUtils", e);
        } finally {
            if (zipFile != null) {
                try {
                    zipFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return srcList;
    }

    /**
     * 递归删除目录下的所有文件及子目录下所有文件
     *
     * @param dir
     *            将要删除的文件目录 true为删除成功，false为删除失败
     */
    public static boolean deleteDir(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            // 递归删除目录中的子目录下
            for (String child : children) {
                boolean success = deleteDir(new File(dir, child));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return dir.delete();
    }

    /**
     * 判断文件大小
     *
     * @param len
     *            文件长度
     * @param size
     *            限制大小
     * @param unit
     *            限制单位（B,K,M,G）
     * @return 返回结果
     */
    public static boolean checkFileSize(Long len, int size, String unit) {
        double fileSize = 0;
        switch (unit.toUpperCase()) {
            case "B":
                fileSize = (double)len;
                break;
            case "K":
                fileSize = (double)len / 1024;
                break;
            case "M":
                fileSize = (double)len / 1048576;
                break;
            case "G":
                fileSize = (double)len / 1073741824;
                break;
            default:
                break;
        }
        return fileSize <= size;
    }

    /**
     * 扫描多个文件
     *
     * @param path
     *            路径
     * @author yzq
     */
    public static List<File> findFile(String path, String type) {
        File file = new File(path);
        File[] list = file.listFiles();
        List<File> name = new ArrayList<>();
        if (list != null) {

            for (File value : list) {
                if (value.isFile() && value.getName().endsWith(type) && !"zip".equals(type)) {
                    name.add(value);
                }
            }
        }
        return name;
    }
}
