package com.qmth.teachcloud.common.util;

import com.qmth.boot.core.fss.service.FileService;
import com.qmth.teachcloud.common.config.DictionaryConfig;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.UploadFileEnum;
import org.apache.commons.codec.digest.DigestUtils;
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 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;
        if ("public".equals(type)){
            server = dictionaryConfig.fssPublicDomain().getServer();
        }else if ("private".equals(type)){
            server = dictionaryConfig.fssPrivateDomain().getServer();
        }else {
            throw ExceptionResultEnum.ERROR.exception("文件存储store类型不存在");
        }

        return server + "/" + objectPath;
    }

    /**
     * 根据数据库文件路径判断文件上传类型
     * @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 异常
     */
    private File saveLocal(InputStream inputStream, String dirPath) throws IOException {
        File desFile = new File(dirPath);
        if (!desFile.getParentFile().exists()) {
            desFile.getParentFile().mkdirs(); //目标文件目录不存在的话需要创建目录
        }
        byte[] bytes = new byte[1024]; // 开辟一个拷贝缓冲区
        try (OutputStream outputStream = new FileOutputStream(desFile)) {
            int length;
            while ((length = inputStream.read(bytes)) != -1) { //当读到尽头后，返回值为-1这个时候停止输出，拷贝结束
                outputStream.write(bytes, 0, length);
            }
            return desFile;
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
    }
}
