package com.artfess.poi.util;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.util.FileUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;


/**
 * 文件下载工具类
 *
 * @author min.wu
 * @date 2021-9-29
 */
@Slf4j
public class FileDownloadUtil {

    /**
     * @param response
     * @param fileName //下载后看到的文件名
     * @return 文件名
     */
    public static void fileDownload(final HttpServletResponse response, File file, String fileName) throws Exception {
        byte[] data = FileUtil.readAsByteArray(file);
        fileDownload(response, data, fileName);
    }

    public static void fileDownload(final HttpServletResponse response, InputStream inputStream, String fileName) throws Exception {
        byte[] data = FileUtil.readAsByteArray(inputStream);
        fileDownload(response, data, fileName);
    }


    /**
     * @param response
     * @param fileName //下载后看到的文件名
     * @return 文件名
     */
    public static void fileDownload(final HttpServletResponse response, byte[] data, String fileName) throws Exception {

        fileName = URLEncoder.encode(fileName, "UTF-8");
        response.reset();
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        //解决跨域
        response.setHeader("Access-Control-Allow-origin", "*");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream;charset=UTF-8");
        OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        outputStream.write(data);
        outputStream.flush();
        outputStream.close();
        response.flushBuffer();

    }

    /**
     * 向响应中写入一般文件附件（一般文件下载）
     *
     * @param result 写入byte信息
     */
    public static void writeResponseFile(HttpServletRequest request, HttpServletResponse response, byte[] result, String fileName) {
        // 对fileName进行http编码
        String currentFileName;
        try {
            if (org.apache.commons.lang3.StringUtils.isBlank(fileName)) {
                currentFileName = "temp";
            } else {
                currentFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name());
            }
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage(), e);
            currentFileName = "temp";
        }

        response.setHeader("Content-Length", "" + result.length);
        response.setContentType("application/octet-stream;charset=utf-8");
        // 设置文件名
        response.addHeader("Content-Disposition", "attachment;fileName=" + encodeFileName(request, currentFileName));
        OutputStream out;
        try {
            out = response.getOutputStream();
            out.write(result);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new IllegalArgumentException(e.getMessage(), e);
        }
    }

    /**
     * 编译文件名，解决中文乱码问题
     *
     * @param fileName     * @return
     */
    private static String encodeFileName(HttpServletRequest request, String fileName) {
        String agent = request.getHeader("User-Agent");
        if (org.apache.commons.lang3.StringUtils.isBlank(agent)) {
            try {
                return URLEncoder.encode(fileName, StandardCharsets.UTF_8.name());
            } catch (UnsupportedEncodingException e) {
                log.warn(e.getMessage(), e);
            }
        }

        // 如果条件成立，说明是Firefox或者Safari浏览器
        if (agent.contains("Firefox") || agent.contains("Safari")) {
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        } else if (agent.contains("Chrome")) {
            try {
                fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name());
            } catch (UnsupportedEncodingException e) {
                log.warn(e.getMessage(), e);
            }
        }
        return fileName;
    }

}
