package com.zfire.mall.manager.utils;

import com.zfire.mall.manager.logic.common.CommonLogic;
import com.zfire.mall.manager.utils.oss.OSSUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
public class CompressDownUtil {

    private static final int  BUFFER_SIZE =  1024;

    private CompressDownUtil() {
    }

    /**
     * 设置下载响应头
     */
    public static HttpServletResponse setDownloadResponse(HttpServletResponse response, String downloadName) throws UnsupportedEncodingException {
        response.reset();
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + new String(downloadName.getBytes("utf-8"),"ISO-8859-1"));
        // 这些是对请求头的匹配
        response.setHeader("Access-Control-Allow-Origin","*");
        response.setHeader("Access-Control-Allow-Credentials","true");
        response.setHeader("Access-Control-Allow-Methods","GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH");
        // 这行代码添加相应的的允许字段
        response.setHeader("Access-Control-Allow-Headers","authorization, content-type,x-token");
        response.setHeader("Access-Control-Expose-Headers","X-forwared-port, X-forwarded-host");
        response.setHeader("Vary","Origin,Access-Control-Request-Method,Access-Control-Request-Headers");


        return response;
    }

    public static Integer[] toIntegerArray(String param) {
        return Arrays.stream(param.split(","))
                .map(Integer::valueOf)
                .toArray(Integer[]::new);
    }

    /**
     * 将多个文件压缩到指定输出流中
     *
     * @param files        需要压缩的文件列表
     * @param outputStream 压缩到指定的输出流
     */
    public static void compressZip(List<File> files, OutputStream outputStream) {
        // 包装成ZIP格式输出流
        try (ZipOutputStream zipOutStream = new ZipOutputStream(new BufferedOutputStream(outputStream))) {
            // 设置压缩方法
            zipOutStream.setMethod(ZipOutputStream.DEFLATED);
            // 将多文件循环写入压缩包
            for (int i = 0; i < files.size(); i++) {
                File file = files.get(i);
                FileInputStream filenputStream = new FileInputStream(file);
                byte[] data = new byte[(int) file.length()];
                filenputStream.read(data);
                // 添加ZipEntry，并ZipEntry中写入文件流，这里，加上i是防止要下载的文件有重名的导致下载失败
                zipOutStream.putNextEntry(new ZipEntry(i + "-" + file.getName()));
                zipOutStream.write(data);
                filenputStream.close();
                zipOutStream.closeEntry();
            }
        } catch (IOException e) {
            log.error(CompressDownUtil.class.getName(), "downloadallfiles", e);
        } finally {
            try {
                if (Objects.nonNull(outputStream)) {
                    outputStream.close();
                }
            } catch (IOException e) {
                log.error(CompressDownUtil.class.getName(), "downloadallfiles", e);
            }
        }
    }

    private static HttpResponse invokeGetFile(String url, CloseableHttpClient httpclient) {

        HttpResponse response;
        try {
            HttpGet get = new HttpGet(url);
            get.setHeader("Content-type", "UTF-8");
            get.setHeader("Connection", "close");
            response = httpclient.execute(get);

        } catch (Exception e) {
            log.error("请求文件异常");
            return null;
        }
        return response;
    }



    public static void compressZipByName(List<Map<String,String>> files, OutputStream outputStream, OSSUtil ossUtil, CommonLogic commonLogic) {
        // 包装成ZIP格式输出流
        try (ZipOutputStream zipOutStream = new ZipOutputStream(new BufferedOutputStream(outputStream))) {
            //  设置压缩方法
            zipOutStream.setMethod(ZipOutputStream.DEFLATED);
            // 将多文件循环写入压缩包
            for (int i = 0; i < files.size(); i++) {
                String url = ossUtil.getUrl(files.get(i).get("path"));
                InputStream inputStream = commonLogic.getFileInputStreamByUrl(url);
                byte [] content = new byte[BUFFER_SIZE];
                int len;
                zipOutStream.putNextEntry(new ZipEntry(i+"-"+files.get(i).get("fileName")));
                while((len=inputStream.read(content))!=-1){
                    zipOutStream.write(content,0,len);
                   // zipOutStream.flush();
                }
                zipOutStream.closeEntry();
                if (inputStream != null) {
                    inputStream.close();
                }
            }
        } catch (IOException e) {
            log.error(CompressDownUtil.class.getName(), "downloadallfiles", e);
        } finally {
            try {
                if (Objects.nonNull(outputStream)) {
                    outputStream.close();
                }
            } catch (IOException e) {
                log.error(CompressDownUtil.class.getName(), "downloadallfiles", e);
            }
        }
    }



    /**
     * 下载文件
     *
     * @param outputStream 下载输出流
     * @param zipFilePath  需要下载文件的路径
     */
    public static void downloadFile(OutputStream outputStream, String zipFilePath) {
        File zipFile = new File(zipFilePath);
        if (!zipFile.exists()) {
            // 需要下载压塑包文件不存在
            return;
        }
        try (FileInputStream inputStream = new FileInputStream(zipFile)) {
            byte[] data = new byte[(int) zipFile.length()];
            inputStream.read(data);
            outputStream.write(data);
            outputStream.flush();
        } catch (IOException e) {
            log.error(CompressDownUtil.class.getName(), "downloadZip", e);
        } finally {
            try {
                if (Objects.nonNull(outputStream)) {
                    outputStream.close();
                }
            } catch (IOException e) {
                log.error(CompressDownUtil.class.getName(), "downloadZip", e);
            }
        }
    }

    /**
     * 删除指定路径的文件
     *
     * @param filepath 文件路径
     */
    public static void deleteFile(String filepath) {
        File file = new File(filepath);
        deleteFile(file);
    }

    /**
     * 删除指定文件
     *
     * @param file 文件
     */
    public static void deleteFile(File file) {
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
        }
    }
}
