package com.yh.saas.plugin.base.utils;

import com.yh.saas.common.support.util.IdGenerator;
import org.springframework.web.util.UriUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class DownFileZipUtils {


    public static String getFilePath(List<File> versionZip, String fillPath, String zipName) {
        //压缩文件地址以及文件名
        String fileZip = fillPath + File.separator + IdGenerator.generateUUID() + File.separator;
        File fileZipDir = new File(fileZip);
        fileZipDir.mkdir();
        fileZip += zipName;
        OutputStream os = null;
        try {
            os = new FileOutputStream(new File(fileZip));
            //调用压缩方法
            toZip(versionZip, os);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return fileZip;
    }


    /**
     * 压缩成ZIP 方法2
     *
     * @param srcFiles 需要压缩的文件列表
     * @param out      压缩文件输出流
     * @throws RuntimeException 压缩失败会抛出运行时异常
     */
    public static void toZip(List<File> srcFiles, OutputStream out) throws RuntimeException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(out);
            for (File srcFile : srcFiles) {
                byte[] buf = new byte[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();
                }
            }
        }
    }

    /**
     * 批量下载文件
     *
     * @param url 附件URL列表
     * @throws IOException
     */
    public static void downloadFiles(String url, String zipName, HttpServletResponse response, HttpServletRequest request) throws IOException {
        response.reset();
        response.setContentType("multipart/form-data");
        response.setHeader("Location", convertFileName(zipName, request));
        response.setHeader("Cache-Control", "max-age=0");
        response.setHeader("Content-Disposition", "attachment; filename=" + convertFileName(zipName, request));
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        response.setHeader("Access-Control-Allow-Credentials", "true");

        File zipFile = new File(url);
        try (BufferedInputStream buff = new BufferedInputStream(new FileInputStream(zipFile));
             BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream())) {
            byte[] car = new byte[5024];
            int l = 0;
            while (l < zipFile.length()) {
                int j = buff.read(car, 0, 1024);
                l += j;
                out.write(car, 0, j);
            }
        } finally {
            Files.delete(zipFile.toPath());
        }
    }

    /**
     * 转换文件名为前端可识别名称
     *
     * @param fileName 文件名称
     * @return 前端可识别文件名称
     */
    private static String convertFileName(String fileName, HttpServletRequest request) {
        String header = request.getHeader("User-Agent").toUpperCase();
        if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
            // IE下载文件名空格变+号问题
            return UriUtils.encode(fileName, StandardCharsets.UTF_8).replace("+", "%20");
        } else {
            return new String(fileName.getBytes(), StandardCharsets.ISO_8859_1);
        }
    }
}
