package com.gyee.runeconomy.util;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
public class FileUtil {

    /**
     * 写入文件
     *
     * @param fileName
     * @param content
     */
    public static boolean writeFile(String fileName, String content) {
        BufferedWriter bw = null;

        try {
            File file = new File(fileName);
            if (!file.exists()) {
//                fileName = fileName.substring(0, fileName.lastIndexOf("\\"));
//                File file1 = new File(fileName);
//                file1.mkdirs();
                file.createNewFile();
            }


            bw = new BufferedWriter(new FileWriter(file, true));

            String[] list = content.split("\n");
            for (int i = 0; i < list.length; i++) {
                bw.write(list[i]);
                bw.write("\n");
                if (i % 1000 == 0)
                    bw.flush();
            }
            bw.flush();
        } catch (Exception e) {
            log.error("writePowerData", e);
            return false;
        } finally {
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return true;
    }

    /**
     * 写入文件
     *
     * @param path
     * @param fileName
     * @param inputStream
     */
    public static void writeFile(String path, String fileName, InputStream inputStream) {
        OutputStream os = null;
        try {
            byte[] bs = new byte[1024];
            int len;

            File file = new File(path);
            if (!file.exists()) {
                file.mkdirs();
            }
            os = new FileOutputStream(file.getPath() + File.separator + fileName);
            // 开始读取
            while ((len = inputStream.read(bs)) != -1) {
                os.write(bs, 0, len);
            }

        } catch (IOException e) {
            log.error(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        } finally {
            // 完毕，关闭所有链接
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }
    }


    // String -> InputStream
    public static InputStream convertStringToInputStream(String content) {

        InputStream result = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
        return result;

    }

    /**
     * 读取文件
     *
     * @param fileName
     * @param isAll    是否读取全部数据
     * @return
     */
    public static List<String> readFile(String fileName, boolean isAll) {
        List<String> list = new ArrayList<>();
        BufferedReader reader = null;

        try {
            File file = new File(fileName);
            reader = new BufferedReader(new FileReader(file));
            String content = null;
            int line = 0;
            // 一次读入一行，直到读入null为文件结束
            while ((content = reader.readLine()) != null) {
                // 显示行号
                list.add(content);
                line++;
                if (!isAll && line == 300)
                    break;
            }
            reader.close();
        } catch (IOException e) {
            log.error(e.getMessage());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }

        return list;
    }


    /**
     * 加载文件
     *
     * @param fileName
     * @return
     */
    public static void download(String fileName, HttpServletResponse response) {
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        try {
            // 获取文件
            File file = new File(fileName);
            // 清空缓冲区，状态码和响应头(headers)
            response.reset();
            // 设置ContentType，响应内容为二进制数据流，编码为utf-8，此处设定的编码是文件内容的编码
            response.setContentType("application/octet-stream;charset=utf-8");
            // 以（Content-Disposition: attachment; filename="filename.jpg"）格式设定默认文件名，设定utf编码，此处的编码是文件名的编码，使能正确显示中文文件名
            response.setHeader("Content-Disposition", "attachment;fileName=" + file.getName() + ";filename*=utf-8''" + URLEncoder.encode(file.getName(), "utf-8"));

            // 实现文件下载
            byte[] buffer = new byte[1024];
            fis = new FileInputStream(file);
            bis = new BufferedInputStream(fis);
            // 获取字节流
            OutputStream os = response.getOutputStream();
            int i = bis.read(buffer);
            while (i != -1) {
                os.write(buffer, 0, i);
                i = bis.read(buffer);
            }
        } catch (Exception e) {
            log.error("FileUtil--download", e);
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    /**
     * @describe 压缩多个文件
     * @author zfc
     */
    public static String zipFiles(List<File> srcFiles, File zipFile) {
        // 判断压缩后的文件存在不，不存在则创建
        if (!zipFile.exists()) {
            try {
                String fileName = zipFile.getAbsolutePath();
                fileName = fileName.substring(0, fileName.lastIndexOf("\\"));
                File file1 = new File(fileName);
                file1.mkdirs();
                zipFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 创建 FileOutputStream 对象
        FileOutputStream fileOutputStream = null;
        // 创建 ZipOutputStream
        ZipOutputStream zipOutputStream = null;
        // 创建 FileInputStream 对象
        FileInputStream fileInputStream = null;

        try {
            // 实例化 FileOutputStream 对象
            fileOutputStream = new FileOutputStream(zipFile);
            // 实例化 ZipOutputStream 对象
            zipOutputStream = new ZipOutputStream(fileOutputStream);
            // 创建 ZipEntry 对象
            ZipEntry zipEntry = null;
            // 遍历源文件数组
            for (int i = 0; i < srcFiles.size(); i++) {
                // 将源文件数组中的当前文件读入 FileInputStream 流中
                fileInputStream = new FileInputStream(srcFiles.get(i));
                // 实例化 ZipEntry 对象，源文件数组中的当前文件
                zipEntry = new ZipEntry(srcFiles.get(i).getName());
                zipOutputStream.putNextEntry(zipEntry);
                // 该变量记录每次真正读的字节个数
                int len;
                // 定义每次读取的字节数组
                byte[] buffer = new byte[1024];
                while ((len = fileInputStream.read(buffer)) > 0) {
                    zipOutputStream.write(buffer, 0, len);
                }
            }
            zipOutputStream.closeEntry();
            zipOutputStream.close();
            fileInputStream.close();
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return zipFile.getAbsolutePath();
    }

    /**
     * 从文件中获取字符串
     *
     * @param path 路径
     * @return 字符串
     */
    public static String getStringFromFile(String path) {
        BufferedReader bufferedReader = null;
        File file = new File(path);
        if (!file.exists()) {
            return "";
        }
        try {
            bufferedReader = new BufferedReader(new FileReader(file));
            StringBuilder sb = new StringBuilder();
            String s = null;
            while ((s = bufferedReader.readLine()) != null) {
                sb.append(s);
            }
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                assert bufferedReader != null;
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }
}
