package com.qmth.teachcloud.exchange.common.util;

import com.qmth.boot.core.fss.service.FileService;
import com.qmth.teachcloud.exchange.common.config.DictionaryConfig;
import com.qmth.teachcloud.exchange.common.enums.UploadFileEnum;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;

/**
 * @Description: 文件存储工具类
 * @Author: CaoZixuan
 * @Date: 2021-08-17
 */
@Component
public class FileStoreUtil {
    private final static Logger log = LoggerFactory.getLogger(FileStoreUtil.class);

    @Resource
    private FileService fileService;

    @Resource
    private DictionaryConfig dictionaryConfig;

    /**
     * 上传文件
     *
     * @param dirName     上传到地址
     * @param inputStream 流
     * @param type        fileStore类型
     */
    public void ossUpload(String dirName, InputStream inputStream, String md5, String type) throws Exception {
        log.info("ossUpload is come in");
        fileService.getFileStore(type).write(dirName, inputStream, md5);
        log.info("dirName:{}", dirName);
    }

//    /**
//     * 上传文件到本地
//     *
//     * @param dirName     上传到地址
//     * @param inputStream 流
//     * @param catalogType 文件
//     */
//    public void localUpload(String dirName, InputStream inputStream, String md5, LocalCatalogEnum catalogType) throws Exception {
//        log.info("ossUpload is come in");
//        String configPath = "";
//        switch (catalogType) {
//            case LOCAL_FILE:
//                configPath = dictionaryConfig.fssLocalFileDomain().getConfig();
//                break;
//            case LOCAL_PDF:
//                configPath = dictionaryConfig.fssLocalPdfDomain().getConfig();
//                break;
//            default:
//                break;
//        }
//        dirName = dirName.replaceAll(configPath, "");
//        fileService.getFileStore(catalogType.getType()).write(dirName, inputStream, md5);
//        log.info("dirName:{}", dirName);
//    }

//    /**
//     * 上传文件到本地
//     *
//     * @param inputStream 流
//     * @param finalFile   最终文件
//     * @param catalogType 文件类型
//     * @throws Exception 异常
//     */
//    public void copyInputStreamToFile(InputStream inputStream, File finalFile, String md5, LocalCatalogEnum catalogType) throws Exception {
//        String dirName = finalFile.getPath().replaceAll("\\\\", "/");
//        this.localUpload(dirName, inputStream, md5, catalogType);
//    }

    /**
     * 上传文件
     *
     * @param dirName 上传到地址
     * @param file    文件
     * @param type    fileStore类型
     */
    public void ossUpload(String dirName, File file, String md5, String type) throws Exception {
        log.info("ossUpload is come in");
        fileService.getFileStore(type).write(dirName, new FileInputStream(file), md5);
        log.info("dirName:{}", dirName);
    }

    /**
     * 上传文件
     *
     * @param dirName 上传到地址
     * @param content 文件
     * @param type    fileStore类型
     */
    public void ossUpload(String dirName, String content, String type) throws Exception {
        log.info("ossUpload is come in");
        fileService.getFileStore(type).write(dirName, new ByteArrayInputStream(content.getBytes()), DigestUtils.md5Hex(new ByteArrayInputStream(content.getBytes())));
        log.info("dirName:{}", dirName);
    }

    /**
     * 从文件存储上下载文件到本地
     *
     * @param dirName   文件地址
     * @param localPath 本地路径
     * @param type      fileStore类型
     * @throws Exception 异常
     */
    public File ossDownload(String dirName, String localPath, String type) throws Exception {
        log.info("ossDownload is come in");
        return this.saveLocal(fileService.getFileStore(type).read(dirName), localPath);
    }


    /**
     * 从文件存储上下载文件到byte[]
     *
     * @param objectName 文件地址
     * @param type       fileStore类型
     * @throws Exception 异常
     */
    public byte[] ossDownload(String objectName, String type) throws Exception {
        log.info("oss Download is come in");
        return IOUtils.toByteArray(fileService.getFileStore(type).read(objectName));
    }

    /**
     * 从文件存储上下载文件到InputStream
     *
     * @param objectName 文件地址
     * @param type       fileStore类型
     * @throws Exception 异常
     */
    public InputStream ossDownloadIs(String objectName, String type) throws Exception {
        log.info("oss Download is come in");
        return fileService.getFileStore(type).read(objectName);
    }


    /**
     * 获取文件访问url
     *
     * @param objectPath 文件路径
     * @param type       文件上传的类型
     * @return
     */
    public String getPrivateUrl(String objectPath, String type) {
        String server = null;
//        if ("public".equals(type)) {
        server = dictionaryConfig.fssPublicDomain().getServer();
        return server + File.separator + objectPath;
//        } else if ("private".equals(type)) {
//            Boolean oss = dictionaryConfig.sysDomain().isOss();
//            if (Objects.nonNull(oss) && oss) {
//                FileStore fileStore = fileService.getFileStore(type);
//                return fileStore.getPresignedUrl(objectPath, Duration.ofMinutes(5L));
//            } else {
//                return dictionaryConfig.fssPrivateDomain().getServer() + "/" + objectPath;
//            }
//        } else {
//            throw ExceptionResultEnum.ERROR.exception("文件存储store类型不存在");
//        }
    }

    /**
     * 根据数据库文件路径判断文件上传类型
     *
     * @param path 路径
     * @return 类型
     */
    public UploadFileEnum getUploadEnumByPath(String path) {
        path = path.replaceAll("\\\\", "/");
        String target = path.substring(0, path.indexOf('/'));
        return UploadFileEnum.valueOf(target.toUpperCase());
    }

    /**
     * 文件存在某本地路径
     *
     * @param inputStream 输入流
     * @param dirPath     本地路径
     * @return 存好的文件
     * @throws IOException 异常
     */
    public File saveLocal(InputStream inputStream, String dirPath) throws IOException {
        String fileName = dirPath.substring(dirPath.lastIndexOf(File.separator) + 1);
        String parentPath = dirPath.substring(0, dirPath.lastIndexOf(File.separator)) + File.separator;
        String name = fileName.substring(0, fileName.lastIndexOf('.'));
        String suffix = fileName.substring(fileName.lastIndexOf('.'));

        File desFile = buildSingleFileName(parentPath, name, suffix, 0);
        if (!desFile.exists()) {
            desFile.getParentFile().mkdirs(); //目标文件目录不存在的话需要创建目录
            desFile.createNewFile();
        }
//        if (desFile.length() > 0) {
//            return desFile;
//        }
        try {
            FileUtils.copyInputStreamToFile(inputStream, desFile);
            return desFile;
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
    }

    /**
     * 构建唯一的文件名称
     *
     * @param path     文件路径
     * @param fileName 文件名称
     * @param suffix   文件后缀
     * @param index    当前下标，初次为0
     * @return 唯一的文件名称
     */
    public static File buildSingleFileName(String path, String fileName, String suffix, Integer index) {
        File file;
        //下标不等于0开始拼后缀
        if (index != 0) {
            file = new File(path + fileName + "(" + index + ")" + suffix);
        } else {
            file = new File(path + fileName + suffix);
        }
        //判断文件是否存在 文件不存在退出递归
        if (file.isFile()) {
            //每次递归给下标加1
            file = buildSingleFileName(path, fileName, suffix, ++index);
        }
        return file;
    }
}
