package com.qmth.teachcloud.common.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.domain.AliYunOssDomain;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Description: oss工具
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/4/4
 */
@Component
public class OssUtil {
    private final static Logger log = LoggerFactory.getLogger(OssUtil.class);

    AliYunOssDomain aliYunOssDomain;

    OSS ossClient;

    @Bean
    public AliYunOssDomain ossDomain(AliYunOssDomain aliYunOssDomain) {
        this.aliYunOssDomain = aliYunOssDomain;
        this.ossClient = new OSSClientBuilder().build(this.aliYunOssDomain.getEndpoint(), this.aliYunOssDomain.getAccessKeyId(), this.aliYunOssDomain.getAccessKeySecret());
        return this.aliYunOssDomain;
    }

    /**
     * oss上传文件
     *
     * @param dirName
     * @param inputStream
     * @param md5
     */
    public void ossUpload(String dirName, InputStream inputStream, String md5) throws IOException {
        log.info("ossUpload is come in");
        ObjectMetadata meta = new ObjectMetadata();
        if (Objects.nonNull(md5)) {
            // 设置MD5校验。
            meta.setContentMD5(md5);
        }
        PutObjectRequest putObjectRequest = new PutObjectRequest(this.aliYunOssDomain.getBucket(), dirName, inputStream, meta);
        PutObjectResult por = this.ossClient.putObject(putObjectRequest);
        log.info("dirName:{},requestid:{}", dirName, por.getRequestId());
    }

    /**
     * oss上传文件
     *
     * @param dirName
     * @param file
     * @param md5
     */
    public void ossUpload(String dirName, File file, String md5) {
        log.info("ossUpload is come in");
        ObjectMetadata meta = new ObjectMetadata();
        if (Objects.nonNull(md5)) {
            // 设置MD5校验。
            meta.setContentMD5(md5);
        }
        PutObjectRequest putObjectRequest = new PutObjectRequest(this.aliYunOssDomain.getBucket(), dirName, file);
        PutObjectResult por = this.ossClient.putObject(putObjectRequest);
        log.info("dirName:{},requestid:{}", dirName, por.getRequestId());
    }

    /**
     * oss上传文件
     *
     * @param dirName
     * @param content
     */
    public void ossUpload(String dirName, String content) {
        log.info("ossUpload is come in");
        PutObjectRequest putObjectRequest = new PutObjectRequest(this.aliYunOssDomain.getBucket(), dirName, new ByteArrayInputStream(content.getBytes()));
        PutObjectResult por = ossClient.putObject(putObjectRequest);
        log.info("dirName:{},requestid:{}", dirName, por.getRequestId());
    }

    /**
     * oss copy
     *
     * @param dirName
     * @param dirNewName
     */
    public void ossCopy(String dirName, String dirNewName) {
        log.info("ossCopy is come in");
        CopyObjectResult result = ossClient.copyObject(this.aliYunOssDomain.getBucket(), dirName, this.aliYunOssDomain.getBucket(), dirNewName);
        log.info("ETag:{},LastModified:{}", result.getETag(), result.getLastModified());
    }

    /**
     * 从oss上下载文件到本地
     *
     * @param dirName
     * @param localPath
     * @throws IOException
     */
    public File ossDownload(String dirName, String localPath) throws IOException {
        log.info("ossDownload is come in");
        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖，不存在则新建。
        File localFile = new File(localPath);
        if (!localFile.getParentFile().exists()) {
            localFile.getParentFile().mkdirs();
        }
        ossClient.getObject(new GetObjectRequest(this.aliYunOssDomain.getBucket(), dirName), localFile);
        return localFile;
    }

    /**
     * 从oss上下载文件到byte[]
     *
     * @param objectName
     * @throws IOException
     */
    public byte[] ossDownload(String objectName) throws IOException {
        log.info("oss Download is come in");
        OSSObject obj = ossClient.getObject(new GetObjectRequest(this.aliYunOssDomain.getBucket(), objectName));
        byte[] data = IOUtils.toByteArray(obj.getObjectContent());
        obj.close();
        return data;
    }

    /**
     * oss删除文件
     *
     * @param dirName
     */
    public void ossDelete(String dirName) {
        ossClient.deleteObject(this.aliYunOssDomain.getBucket(), dirName);
    }

    /**
     * oss批量删除文件
     *
     * @param paths
     */
    public void ossBatchDelete(List<String> paths) {
        // 删除文件。key等同于ObjectName，表示删除OSS文件时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
        DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(this.aliYunOssDomain.getBucket()).withKeys(paths));
        deleteObjectsResult.getDeletedObjects();
    }

    /**
     * 获取私有bucket文件访问url
     *
     * @param objectPath
     * @return
     */
    public String getPrivateUrl(String objectPath) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MILLISECOND, SystemConstant.OSS_URL_EXPIRE);
        GeneratePresignedUrlRequest generatePresignedUrlRequest;
        generatePresignedUrlRequest = new GeneratePresignedUrlRequest(this.aliYunOssDomain.getBucket(), objectPath);
        generatePresignedUrlRequest.setExpiration(calendar.getTime());
        return ossClient.generatePresignedUrl(generatePresignedUrlRequest).toString();
    }
}
