package com.qs.mp.common.qcloud;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.GetObjectRequest;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import com.qs.mp.common.utils.LogUtil;
import java.io.File;
import java.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @author zhongcp
 * @Date 2021/9/18
 */
@Component
public class QcloudFileUtils {

  private static final Logger logger = LoggerFactory.getLogger(QcloudFileUtils.class);

  private static COSClient cosClient;

  private static String accessKey;

  @Value("${cloud.accessKey}")
  public void setAccessKey(String accessKeyParam) {
    accessKey = accessKeyParam;
  }

  private static String secretKey;

  @Value("${cloud.secretKey}")
  public void setSecretKey(String secretKeyParam) {
    secretKey = secretKeyParam;
  }

  private static String region;

  @Value("${cloud.region}")
  public void setRegion(String regionParam) {
    region = regionParam;
  }

  public static COSClient getCosClient() {
    if (null == cosClient) {
      cosClient = createCli(region);
    }
    return cosClient;
  }

  static COSClient createCli(String region) {
    // 初始化用户身份信息(secretId, secretKey)
    COSCredentials cred = new BasicCOSCredentials(accessKey, secretKey);
    // 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
    ClientConfig clientConfig = new ClientConfig(new Region(region));
    // 生成cos客户端
    return new COSClient(cred, clientConfig);
  }

  public static void putFile(File file, String key, String bucketName, String contentType) {

    ObjectMetadata objectMetadata = new ObjectMetadata();
//    objectMetadata.setHeader("expires", new Date(1660000000000L));
    objectMetadata.setContentType(contentType);
    PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, file);
    putObjectRequest.withMetadata(objectMetadata);

    PutObjectResult putObjectResult = getCosClient().putObject(putObjectRequest);

    LogUtil.info(logger, "put file reqId: " + putObjectResult.getRequestId());
  }

  public static void putStream(InputStream stream, String key, String bucketName,
      String contentType)
      throws InterruptedException {

    ObjectMetadata objectMetadata = new ObjectMetadata();
    objectMetadata.setContentType(contentType);
    PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, stream, objectMetadata);
//    putObjectRequest.withMetadata(objectMetadata);

    PutObjectResult putObjectResult = getCosClient().putObject(putObjectRequest);

    LogUtil.info(logger, "put file reqId: " + putObjectResult.getRequestId());

    /*ObjectMetadata objectMetadata = new ObjectMetadata();
//    objectMetadata.setHeader("expires", new Date(1660000000000L));

    ExecutorService threadPool = Executors.newFixedThreadPool(2);
    // 传入一个threadpool, 若不传入线程池, 默认TransferManager中会生成一个单线程的线程池。
    TransferManager transferManager = new TransferManager(cosClient, threadPool);

    PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, stream,
        objectMetadata);

    // 返回一个异步结果Upload, 可同步的调用waitForUploadResult等待upload结束, 成功返回UploadResult, 失败抛出异常.
    long startTime = System.currentTimeMillis();
    Upload upload = transferManager.upload(putObjectRequest);
//    showTransferProgress(upload);
    UploadResult uploadResult = upload.waitForUploadResult();
    long endTime = System.currentTimeMillis();
    LogUtil.info(logger, "upload used time: " + (endTime - startTime) / 1000);
    LogUtil.info(logger, "upload result: {0}", JSONObject.toJSONString(uploadResult));
    transferManager.shutdownNow();
    cosClient.shutdown();*/
  }

  public static void downloadFile(String key, String bucketName, String localDir, String saveName) {
    GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, key);
    File localFile = new File(localDir + saveName);
    ObjectMetadata objectMetadata = getCosClient().getObject(getObjectRequest, localFile);

    LogUtil.info(logger, "download file content length:" + objectMetadata.getContentLength());
  }
}
