package com.pz.common.utils.file;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.pz.common.config.FileSystemProperties;
import com.pz.common.exception.ServiceException;
import com.pz.common.utils.DateUtils;
import com.pz.common.utils.StringUtils;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.rmi.ServerException;
import java.util.function.Supplier;

/**
 * 文件上传/下载工具
 * <p>created in  2023/9/8 15:03
 *
 * @author WangMin
 * @version 1.0
 */
@Slf4j
public class FileTool {

    /**
     * 文件系统属性
     */
    @Setter
    private static FileSystemProperties properties;


    /**
     * @param fileName 设置文件名
     * @param file     文件数据
     * @return 文件路径
     */
    public static String upload(MultipartFile file, String fileName) throws IOException {
        if (file == null) {
            throw new ServerException("文件为空");
        }
        String finalName = generateRandomFileName(file, fileName);
        File desc = getAbsoluteFile(finalName);
        file.transferTo(desc);
        return properties.getResponsePath() + "/" + finalName;
    }

    /**
     * 输出指定文件的byte数组
     *
     * @param filePath 文件路径
     * @param os       输出流
     */

    public static void writeBytes(String filePath, OutputStream os) throws IOException {
        try {
            FileInputStream fis = null;
            try {
                File file = new File(filePath);
                if (!file.exists()) {
                    throw new FileNotFoundException(filePath);
                }
                fis = new FileInputStream(file);
                byte[] b = new byte[1024];
                int length;
                while ((length = fis.read(b)) > 0) {
                    os.write(b, 0, length);
                }
            } finally {
                if (os != null) {
                    os.close();
                }
                if (fis != null) {
                    fis.close();
                }
            }
        } catch (Exception e) {
            log.error("文件下载失败,cause:{}", e.getMessage());
            throw e;
        }

    }

    /**
     * 生成文件名(包含文件路径)
     *
     * @param file     文件
     * @param fileName 指定文件名
     * @return 文件路径(相对路径) + 文件名
     */
    private static String generateRandomFileName(MultipartFile file, String fileName) {
        String finalName;
        if (StringUtils.isNotEmpty(fileName)) {
            finalName = fileName;
        } else {
            finalName = IdUtil.fastSimpleUUID();
        }
        return DateUtils.datePath() + "/" + finalName + "." + getExtensionName(file);
    }


    /**
     * 获取文件拓展名
     *
     * @param file 文件
     * @return 文件拓展名
     */
    private static String getExtensionName(MultipartFile file) {
        String extensionName = null;
        if (StringUtils.isNotEmpty(file.getOriginalFilename())) {
            StringBuilder originName = new StringBuilder(file.getOriginalFilename());
            int index = originName.lastIndexOf(".");
            extensionName = index != -1 ? originName.substring(index + 1) : null;
        }
        if (StringUtils.isEmpty(extensionName)) {
            extensionName = MimeTypeUtils.getExtension(() -> StringUtils.isNotEmpty(file.getContentType()) ? file.getContentType() : "");
        }
        return extensionName;
    }

    /**
     * 获取上传文件File
     *
     * @param fileName 文件名称
     * @return file
     */
    private static File getAbsoluteFile(String fileName) {
        File desc = new File(properties.getUploadPath() + File.separator + fileName);
        if (!desc.exists()) {
            if (!desc.getParentFile().exists()) {
                if (!desc.getParentFile().mkdirs()) {
                    throw new ServiceException("文件创建失败");
                }
            }
        }
        return desc;
    }

}