package com.ruoyi.common.qiniu;

import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.ruoyi.common.utils.StringUtils;
import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigInteger;
import java.security.MessageDigest;

/**
 * 七牛云文件存储服务
 * @author Wzp
 */
@Component
public class QiNiuUploadUtils {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /** 磁盘图片配置 */
    @Resource
    private QiNiuConfig qiNiuConfig;

    /** 上传对象 */
    private UploadManager uploadManager;

    /** 上传凭证 */
    private Auth auth;

//    /**
//     * 初始化上传对象
//     */
//    protected void init(){
//        //构造一个带指定 Region 对象的配置类
//        Configuration cfg = new Configuration(Region.huanan());
//        // 指定分片上传版本
//        cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;
//        this.uploadManager = new UploadManager(cfg);
//        // 获取token凭证对象
//        this.auth = Auth.create(qiNiuConfig.getAccessKey(), qiNiuConfig.getSecretKey());
//    }

    /**
     * 上传字节数组
     * @param uploadBytes 字节数组数据
     * @return 结果
     */
    public String  uploadByte(byte[] uploadBytes, String key){
        String fileUrl = "";
        File outputFile = new File(qiNiuConfig.getImgFolderUrl()+"/"+key);
        try (FileOutputStream fos = new FileOutputStream(outputFile)) {
            fos.write(uploadBytes);
        } catch (IOException e) {
            e.printStackTrace();
            logger.error(e.getMessage());
        }finally {
            fileUrl = qiNiuConfig.getLocalBaseUrl()+key;
            return fileUrl;
        }
    }

    /**
     * 数据流上传
     * @param inputStream 数据流
     * @return 结果
     */
    public String uploadInputStream(InputStream inputStream,String key) {
        String url = "";

        File outputFile = new File(qiNiuConfig.getImgFolderUrl()+"/"+key);

        try (FileOutputStream outputStream = new FileOutputStream(outputFile)) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
        } catch (FileNotFoundException e) {
            logger.error(e.getMessage());
            throw new RuntimeException(e);
        } catch (IOException e) {
            logger.error(e.getMessage());
            throw new RuntimeException(e);
        }finally {
            url = qiNiuConfig.getLocalBaseUrl()+key;
            return url;
        }

    }



    /**
     * 获取文件上传名称
     * @param file 文件
     * @return 结果
     */
    public String getFileUploadName(MultipartFile file){
        // 上传文件名
        String fileName = "";
        try {
            // 文件真实名称
            String originalFilename = file.getOriginalFilename();
            if (StringUtils.isNotBlank(originalFilename)){
                // 获取后缀名
                String substring = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
                // 获取文件hash值
                String s = md5HashCode(file.getInputStream());
                fileName = s+"."+substring;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileName;
    }

    /**
     * java获取文件的md5值
     * @param fis 输入流
     * @return 结果
     */
    public static String md5HashCode(InputStream fis) {
        try {
            //拿到一个MD5转换器,如果想使用SHA-1或SHA-256，则传入SHA-1,SHA-256
            MessageDigest md = MessageDigest.getInstance("MD5");

            //分多次将一个文件读入，对于大型文件而言，比较推荐这种方式，占用内存比较少。
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length = fis.read(buffer, 0, 1024)) != -1) {
                md.update(buffer, 0, length);
            }
            fis.close();
            //转换并返回包含16个元素字节数组,返回数值范围为-128到127
            byte[] md5Bytes  = md.digest();
            BigInteger bigInt = new BigInteger(1, md5Bytes);//1代表绝对值
            return bigInt.toString(16);//转换为16进制
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 图片压缩
     * @param file 文件
     * @return 字节数组
     */
    public static byte[] getZipImage(MultipartFile file) {
        byte[] zipBytes = null;
        ByteArrayOutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            byte[] bytes = file.getBytes();
            outputStream = new ByteArrayOutputStream(bytes.length);
            inputStream = file.getInputStream();
            Thumbnails.of(inputStream)
                    .scale(0.8f)
                    .outputQuality(1f)
                    .toOutputStream(outputStream);
            zipBytes = outputStream.toByteArray();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return zipBytes;
    }

}
