package com.bcxin.autodownloadupload.common.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;

/**
 * description: 文件工具类
 * author: linchunpeng
 * date:  2023-04-18 15:15
 */
@Slf4j
public class FileUtils {


    /**
     * description: 根据url下载文件
     * author: linchunpeng
     * date:  2023-04-18 15:15
     */
    public static String downloadByUrl(String urlStr, String savePath) throws Exception {
        InputStream inputStream = null;
        FileOutputStream fos = null;
        try {
            URL url = new URL(urlStr);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //设置超时间为5秒
            conn.setConnectTimeout(5 * 1000);
            //防止屏蔽程序抓取而返回403错误
            conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            //设置部分请求头信息，根据自己的实际需要来书写，不需要的也可以删掉
            conn.setRequestProperty("api_token", "Bearer_");
            conn.setRequestProperty("Cookie", "XXL_JOB_LOGIN_IDENTITY=");
            //得到输入流
            inputStream = conn.getInputStream();
            //获取自己数组
            byte[] getData = readInputStream(inputStream);
            //文件保存位置
            if (!FileUtil.exist(savePath)) {
                log.info("目录：{}，不存在，创建", savePath);
                FileUtil.mkdir(savePath);
                if (FileUtil.exist(savePath)) {
                    log.info("创建成功");
                } else {
                    log.info("创建失败");
                }
            }

            //获取文件名及后缀
            String headerField = conn.getHeaderField("Content-Disposition");
            String[] split = headerField.split("\"");
            String fileName = URLDecoder.decode(split[1], "utf-8");
            String fileSavePath = savePath + File.separator + fileName;
            //开始写入
            File file = new File(fileSavePath);
            fos = new FileOutputStream(file);
            fos.write(getData);
            log.info("文件: {}，下载成功", urlStr);
            return fileSavePath;
        } catch (Exception e) {
            log.error("文件：{}，下载异常", urlStr, e);
            throw e;
        } finally {
            try {
                if (inputStream != null) inputStream.close();
                if (fos != null) fos.close();
            } catch (Exception e) {
                log.error("文件：{}，关闭流异常", urlStr, e);
            }
        }
    }

    /**
     * 根据url地址下载文件
     * @param fileUrl 文件地址
     * @param localFilePath 保存本地路径
     */
    public static boolean downloadFile(String fileUrl, String localFilePath, String serverUrl, String obsUrl) {
        URL urlfile = null;
        HttpResponse executeAsync = null;
        try {
            if (fileUrl.startsWith("/upload")) {
                if (serverUrl.contains("v5qy.baibaodun.cn")) {
                    //互联网
                    if (fileUrl.startsWith("/uploads")) {
                        fileUrl = fileUrl.substring(8);
                    } else {
                        fileUrl = fileUrl.substring(7);
                    }
                    fileUrl = obsUrl.concat(fileUrl);
                } else {
                    fileUrl = serverUrl.concat(fileUrl);
                }
            }
            if (fileUrl.startsWith("https:/") && !fileUrl.startsWith("https://")) {
                fileUrl = fileUrl.replace("https:/", "https://");
            }
            if (fileUrl.startsWith("http:/") && !fileUrl.startsWith("http://")) {
                fileUrl = fileUrl.replace("http:/", "http://");
            }
            urlfile = new URL(fileUrl);
            String filePath = null;
            String path = urlfile.getPath();
            if (path.equals("/getResource.do")) {  //判断地址是http://bj.baibaodun.cn:8801/ars-web/getResource.do?path=upload/2020-08-28/1598607857060.zip 就截取 =后面的路径
                filePath = fileUrl.substring(fileUrl.indexOf("=") + 1);
            } else if (fileUrl.contains("=")) { //截取双路径如 http://v5qy.baibaodun.cn/obpm/v2/sync/file/download?f=https%3A%2F%2Fbcxin-v5-prod.obs.cn-north-1.myhuaweicloud.com%2Fuploads%2F2022%2F07-12%2F658979513459277824--__AOkTvsah9VLicJhQ1FO%2F1657606996828%2F%E4%BF%9D%E5%AE%89%E6%9C%8D%E5%8A%A1%E5%85%AC%E5%8F%B8%E8%AE%BE%E7%AB%8B%E5%88%86%E5%85%AC%E5%8F%B8%E5%A4%87%E6%A1%88.zip
                if (fileUrl.substring(fileUrl.indexOf("=") + 1).contains("https")) {
                    filePath = fileUrl.substring(fileUrl.indexOf("=") + 1).substring(fileUrl.substring(fileUrl.indexOf("=") + 1).indexOf("com") + 3);
                } else {
                    if (fileUrl.substring(fileUrl.indexOf("=") + 1).indexOf("/") != 0) {
                        filePath = "/" + fileUrl.substring(fileUrl.indexOf("=") + 1);
                    } else {
                        filePath = fileUrl.substring(fileUrl.indexOf("=") + 1);
                    }
                }
            } else {
                filePath = path;
            }
            filePath = filePath.replaceAll("/upload/", "/uploads/");
            if (filePath.contains("/uploads/")) {
                filePath = filePath.substring(filePath.indexOf("/uploads/"));
            } else {
                filePath = "/uploads/" + filePath;
            }
            filePath = filePath.replaceAll("/+", "/");

            File f = new File(localFilePath + filePath);
            if (!f.getParentFile().exists() && !f.getParentFile().isDirectory()) {
                FileUtil.mkdir(f.getParentFile());
                //f.getParentFile().mkdirs();
            }

            HttpRequest get = HttpUtil.createGet(fileUrl, true);
            get.header("accessToken", "eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhdXRoMCIsImV4cCI6MTY2Njg2MDAwMSwidXNlcm5hbWUiOiI3TkVMR1RYaSJ9.Fvx16149p8Grp-a_QwFRGro_sWD1xqL2QV5beL9bRcc");
            executeAsync = get.executeAsync();
            if (executeAsync.getStatus() != 200) {
                return false;
            }
            executeAsync.writeBody(new File(localFilePath+filePath),null);
        } catch (Exception e) {
            log.error("文件：{}，下载异常：{}", fileUrl, e.getMessage());
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (executeAsync != null) executeAsync.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return true;
    }


    /**
     * description: 判断文件是否能访问
     * author: linchunpeng
     * date:  2023-04-23 16:48
     */
    public static boolean checkFileHutool(String fileUrl) {
        HttpResponse executeAsync = null;
        try {
            if (fileUrl.startsWith("https:/")) {
                if (!fileUrl.substring(0, 8).equals("https://")) {
                    fileUrl = fileUrl.replace("https:/", "https://");
                }
            }
            HttpRequest get = HttpUtil.createGet(fileUrl, true);
            get.header("accessToken", "eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhdXRoMCIsImV4cCI6MTY2Njg2MDAwMSwidXNlcm5hbWUiOiI3TkVMR1RYaSJ9.Fvx16149p8Grp-a_QwFRGro_sWD1xqL2QV5beL9bRcc");
            executeAsync = get.executeAsync();
            int status = executeAsync.getStatus();
            if (status != 200) {
                log.info("文件访问失败，访问结果：{}，文件地址：{}", status, fileUrl);
            }
            return status == 200;
        } catch (Exception e) {
            log.error("文件：{}，判断是否能访问异常：{}", fileUrl, e.getMessage());
            e.printStackTrace();
            return false;
        } finally {
            try {
                if (executeAsync != null) executeAsync.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * description: 判断文件是否能访问
     * author: linchunpeng
     * date:  2023-04-23 16:48
     */
    public static boolean checkFile(String fileUrl) {
        try {
            URL url = new URL(fileUrl);
            HttpURLConnection urlcon = (HttpURLConnection) url.openConnection();
            urlcon.setRequestMethod("GET");
            urlcon.setRequestProperty("Content-type", "application/x-www-form-urlencoded");
            int responseCode = urlcon.getResponseCode();
            if (responseCode != 200) {
                log.info("第二次文件访问失败，访问结果：{}，文件地址：{}", responseCode, fileUrl);
            }
            return responseCode == HttpURLConnection.HTTP_OK;
        } catch (Exception e) {
            log.error("文件：{}，第二次访问异常：{}", fileUrl, e.getMessage());
            e.printStackTrace();
            return false;
        }
    }


    /**
     * description: 获取url的连接状态
     * author: linchunpeng
     * date:  2023-04-28 10:17
     */
    public static int getUrlStatus(String fileUrl) {
        HttpResponse executeAsync = null;
        try {
            HttpRequest get = HttpUtil.createGet(fileUrl, true);
            executeAsync = get.executeAsync();
            return executeAsync.getStatus();
        } catch (Exception e) {
            e.printStackTrace();
            return 404;
        } finally {
            try {
                if (executeAsync != null) executeAsync.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * description: 从输入流中获取字节数组
     * author: linchunpeng
     * date:  2023-04-18 15:33
     */
    private static byte[] readInputStream(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[4 * 1024];
        int len = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
        bos.close();
        return bos.toByteArray();
    }


    public static void responseWithFile(String realPath, HttpServletResponse response) throws IOException {
        File selectedFile = new File(realPath);
        response.setContentType("application/x-download; charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=\"" + java.net.URLEncoder.encode(selectedFile.getName(), "UTF-8") + "\"");

        try (ServletOutputStream outputStream = response.getOutputStream()) {
            try (BufferedInputStream reader = new BufferedInputStream(new FileInputStream(selectedFile))) {
                byte[] buffer = new byte[4096];
                int i = -1;
                while ((i = reader.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, i);
                }
            }
            outputStream.flush();
        }
    }

}
