package com.trade.service.filestorage.util;

import java.io.*;
import java.util.Date;
import java.util.UUID;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.trade.service.filestorage.util.watermark.TextMark;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import com.github.pagehelper.util.StringUtil;
import com.trade.service.filestorage.enums.FileModuleEnum;

import javax.servlet.http.HttpServletResponse;

@ConfigurationProperties(prefix = "upload")
@Component
/** 文件辅助工具类 */
public class FileUtil {

    /** 存储磁盘 */
    private static String DISK;
    /** 所有文件存储目录 */
    public static String DIR = "fileResource";
    /** classPath路径 */
    private static String CLASS_PATH;
    /** 资源绝对存储路径 */
    private static String ABSOLUTE_PATH;

    /** spring注入存储配置 */
    public void setDisk(String disk) {
        if (StringUtil.isEmpty(FileUtil.DISK)) {
            FileUtil.DISK = disk;
        }
    }

    /** 资源获取资源路径 */
    public static String getClassPath() {
        if (StringUtil.isEmpty(CLASS_PATH)) {
            CLASS_PATH = FileUtil.class.getResource("/").getPath();
        }
        return CLASS_PATH;
    }

    /** 获取文件后缀 */
    public static String getSuffix(String name) {
        if (!StringUtil.isEmpty(name) && name.indexOf(".") > 0) {
            return name.substring(name.lastIndexOf("."));
        } else {
            return "";
        }
    }

    /** 获取资源绝对存储目录 */
    public static String getAbsoluteDir() {
        if (StringUtil.isEmpty(ABSOLUTE_PATH)) {
            File file = new File(DISK);
            if (!file.exists()) {
                file.mkdirs();
            }
            ABSOLUTE_PATH = file.getAbsolutePath();
        }
        return ABSOLUTE_PATH;
    }

    /** 随机生成文件名称 */
    public static String randomFileName() {
        return UUID.randomUUID().toString();
    }

    /** 获取以日期格式的文件路径 */
    public static String getDatePath() {
        return "/";
    }

    /**
     * 获取文件路径
     * 
     * @param fileName 文件名称
     * @param suffix 文件后缀
     * @param moduleType 文件所属模块枚举实例
     * @return
     */
    public static String getFilePath(String fileName, String suffix, FileModuleEnum moduleType) {
        StringBuilder sb = new StringBuilder("/");
        sb.append(DIR).append("/").append(moduleType.getCode());
        sb.append(getDatePath()).append(fileName);
        if (StringUtil.isNotEmpty(suffix)) {
            sb.append(suffix);
        }
        return sb.toString();
    }

    /**
     * (双钱包)
     * 
     * @param fileName
     * @param suffix
     * @param identifier
     * @return
     */
    public static String getFilePath(String fileName, String suffix, String identifier) {
        StringBuilder sb = new StringBuilder("/").append(DIR).append("/").append(identifier);
        sb.append(getDatePath()).append("/").append(fileName).append(suffix);
        return sb.toString();
    }

    /**
     * 获取资源绝对存储路径
     *
     * @param fileName 文件名称
     * @param suffix 文件后缀
     * @return
     */
    public static String getAbsolutePath(String fileName, String suffix, String identifier) {
        return getAbsoluteDir() + getFilePath(fileName, suffix, identifier);
    }

    /**
     * 获取资源绝对存储路径
     * 
     * @param fileName 文件名称
     * @param suffix 文件后缀
     * @param moduleType 文件所属模块枚举实例
     * @return
     */
    public static String getAbsolutePath(String fileName, String suffix, FileModuleEnum moduleType) {
        return getAbsoluteDir() + getFilePath(fileName, suffix, moduleType);
    }

    /** 在工程的目录下创建需要在线预览生成的文件夹 **/
    public static String getFileOnlinePreviewPath() {
        String newPath = System.getProperty("user.dir") + File.separator + "src" + File.separator + "main"
                + File.separator + "resources" + File.separator + "static" + File.separator + "uploadFile";
        File directoryFile = new File(newPath);
        if (!(directoryFile.exists() && directoryFile.isDirectory())) {
            directoryFile.mkdirs();
        }
        return newPath;
    }

    /** 在工程的目录下创建需要在线预览生成的文件夹 **/
    public static String getOSSFileOnlinePreviewPath() {
        String newPath = "trade-service" + File.separator + "src" + File.separator + "main" + File.separator
                + "resources" + File.separator + "static" + File.separator + "uploadFile";
        File directoryFile = new File(newPath);
        if (!(directoryFile.exists() && directoryFile.isDirectory())) {
            directoryFile.mkdirs();
        }
        return newPath;
    }

    /** 获取工程目录下的，excel的模版文件的路径 **/
    public static String getDataTemplateFilePath() {
        return System.getProperty("user.dir") + File.separator + "src" + File.separator + "main" + File.separator
                + "resources" + File.separator + "static" + File.separator + "dataTemplates" + File.separator;
    }

    public static String getAbsoluteWaterMarkPath() {
        String path = getAbsoluteDir() + File.separator + DIR + File.separator + "watermark";
        File directoryFile = new File(path);
        if (!(directoryFile.exists() && directoryFile.isDirectory())) {
            directoryFile.mkdirs();
        }
        return path;
    }

    public static String getWaterMarkFilePath() {
        StringBuilder sb = new StringBuilder(File.separator);
        sb.append(DIR).append(File.separator).append("watermark");
        sb.append(File.separator);
        return sb.toString();
    }

    public static String getAbsolutePreviewPicturePath() {
        String path = getAbsoluteDir() + File.separator + DIR + File.separator + "temppicture";
        File directoryFile = new File(path);
        if (!(directoryFile.exists() && directoryFile.isDirectory())) {
            directoryFile.mkdirs();
        }
        return path;
    }

    public static String getPreviewPicturePath(String fileName) {
        StringBuilder sb = new StringBuilder(File.separator);
        sb.append(DIR).append(File.separator).append("temppicture");
        sb.append(File.separator).append(fileName);
        return sb.toString();
    }

    /**
     * 判断要生成的文件所在的文件夹是否存在，若不存在，则创建
     *
     * @param filePath 文件路径
     */
    public static void createParentDirection(String filePath) {
        File file = new File(filePath);
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
    }

    /**
     * 根据文件路径删除文件
     * 
     * @param filePath 文件路径
     */
    public static boolean remove(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            return file.delete();
        }
        return false;
    }

    /**
     * 将输入流写入文件
     *
     * @param inputStream 输入流
     * @param filePath 文件路径
     * @return File
     * @throws IOException
     */
    public static File convertInputStreamToFile(InputStream inputStream, String filePath) throws IOException {
        File file = new File(filePath);
        try (OutputStream outputStream = new FileOutputStream(file)) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
            }
        }
        return file;
    }

    /**
     * InputStream流转byte数组
     *
     * @param input InputStream
     * @return byte[]
     * @throws IOException
     */
    public static byte[] toByteArray(InputStream input) throws IOException {
        // 基于内存的读取，要注意大文件的内存溢出问题
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int n;
        while (-1 != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
        }
        return output.toByteArray();
    }


    /**
     * 判断文件的编码格式
     *
     * @return 文件编码格式
     */
    public static String getFileCode(InputStream in) {
        try {
            int p = (in.read() << 8) + in.read();
            String code = "GBK";

            switch (p) {
                case 59524:
                    code = "UTF-8";
                    break;
                case 0xfffe:
                    code = "Unicode";
                    break;
                case 0xfeff:
                    code = "UTF-16BE";
                    break;
                case 48581:
                    code = "GBK";
                    break;
                default:
            }
            return code;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
