package com.xiaoniu.file.service;

import com.alibaba.fastjson2.JSONObject;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import com.xiaoniu.common.core.utils.DateUtils;
import com.xiaoniu.common.core.utils.StringUtils;
import com.xiaoniu.common.core.utils.file.FileTypeUtils;
import com.xiaoniu.common.core.utils.uuid.Seq;
import com.xiaoniu.file.config.QiNiuConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;

/**
 * 七牛云 文件存储
 *
 * @author xiaoniu
 */
@Primary
@Service
public class QiniuSysFileServiceImpl implements ISysFileService
{
    private static final Logger log = LoggerFactory.getLogger(QiniuSysFileServiceImpl.class);


    @Autowired
    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());
    }

    @Override
    public String uploadFile(MultipartFile file) throws Exception {
        String fileUrl = "";
        // 初始化上传对象和凭证
        init();
        // 文件名称
        String key = StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
                md5HashCode(file.getInputStream()), Seq.getId(Seq.uploadSeqType), FileTypeUtils.getExtension(file));
        // 上传
        Response response = uploadManager.put(file.getBytes(), key, auth.uploadToken(qiNiuConfig.getBucketName(), key));
        // 上传结果
        log.info(response.bodyString());
        //解析上传成功的结果
        DefaultPutRet putRet = JSONObject.parseObject(response.bodyString(), DefaultPutRet.class);
        if (StringUtils.isNotBlank(putRet.hash)){
            // 访问链接
            fileUrl = qiNiuConfig.getBaseUrl()+putRet.key;
        }
        return fileUrl;
    }

    /**
     * 获取文件上传名称
     * @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;
//    }
}
