package com.kym.common.utils;

import cn.hutool.core.io.IoUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.*;
import com.kym.common.config.OssConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;


/**
 * 私有写
 * https://oss.console.aliyun.com/bucket/oss-cn-shenzhen/kym-static/overview
 * aliyun 对象存储工具类
 */
public class OssUtil {
    private static Logger logger = LoggerFactory.getLogger(OssUtil.class);
    private static String bucket;

    private OssUtil() {
    }

    private static OSS getClient() {
        OssConfig ossConfig = SpringUtil.getBean(OssConfig.class);
        // Endpoint以华东1（杭州）为例，其它Region请按实际情况填写。
        String endpoint = ossConfig.getEndpoint();
        String keyId = ossConfig.getKeyId();
        String keySecret = ossConfig.getKeySecret();
        bucket = ossConfig.getBucket();
        // 创建OSSClient实例。
        return new OSSClientBuilder().build(endpoint, keyId, keySecret);
    }

    /**
     * 文件上传
     *
     * @param fileId 文件在应用系统中的唯一ID
     * @param file   文件
     */
    public static PutObjectResult upload(String fileId, File file) {
        OSS oss = getClient();

        try {
            PutObjectRequest request = new PutObjectRequest(bucket, fileId, file);
            return oss.putObject(request);
        } catch (Exception ce) {
            logger.error("upload>>>" + ce.getMessage(), ce);
        } finally {
            if (oss != null) {
                oss.shutdown();
            }
        }
        return null;
    }


    public static void download(String fileId, File destFile) {
        OSS oss = getClient();
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            // 调用ossClient.getObject返回一个OSSObject实例，该实例包含文件内容及文件元信息。
            OSSObject ossObject = oss.getObject(bucket, fileId);
            // 调用ossObject.getObjectContent获取文件输入流，可读取此输入流获取其内容。
            inputStream = ossObject.getObjectContent();
            outputStream = Files.newOutputStream(destFile.toPath());
            IoUtil.copy(inputStream, outputStream);
        } catch (Exception ce) {
            logger.error("download >>>" + ce.getMessage(), ce);
        } finally {
            if (oss != null) {
                oss.shutdown();
            }
            IoUtil.close(outputStream);
            IoUtil.close(inputStream);
        }
    }


    public static void delete(String fileId) {
        OSS oss = getClient();
        try {
            // 删除文件。
            oss.deleteObject(bucket, fileId);
        } catch (Exception ce) {
            logger.error("delete >>>" + ce.getMessage(), ce);
        } finally {
            if (oss != null) {
                oss.shutdown();
            }
        }
    }


    /**
     * 使用AK&SK初始化账号Client
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */
//    public static com.aliyun.sts20150401.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
//        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
//                // 必填，您的 AccessKey ID
//                .setAccessKeyId(accessKeyId)
//                // 必填，您的 AccessKey Secret
//                .setAccessKeySecret(accessKeySecret);
//        // Endpoint 请参考 https://api.aliyun.com/product/Sts
//        config.endpoint = "sts.cn-shenzhen.aliyuncs.com";
//        return new com.aliyun.sts20150401.Client(config);
//    }
//
//    public static AssumeRoleResponse getSts() throws Exception {
//        // 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
//        // 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取 AccessKey 的方式进行调用，仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378657.html
//        com.aliyun.sts20150401.Client client = createClient("LTAI5tEPpmhZGDRb6sgqhiA2", "HjlRw844NVP894jAzZna45Vns6axes");
//        com.aliyun.sts20150401.models.AssumeRoleRequest assumeRoleRequest = new com.aliyun.sts20150401.models.AssumeRoleRequest()
//                .setDurationSeconds(3600L)
////                .setPolicy("AliyunOSSFullAccess")
//                .setRoleArn("acs:ram::1757940634296846:role/aliyunosstokengeneratorrole")
//                .setRoleSessionName("AliyunOSSTokenGeneratorRole");
//        try {
//            // 复制代码运行请自行打印 API 的返回值
//            return client.assumeRoleWithOptions(assumeRoleRequest, new com.aliyun.teautil.models.RuntimeOptions());
//        } catch (TeaException error) {
//            // 如有需要，请打印 error
//            com.aliyun.teautil.Common.assertAsString(error.message);
//        } catch (Exception _error) {
//            TeaException error = new TeaException(_error.getMessage(), _error);
//            // 如有需要，请打印 error
//            com.aliyun.teautil.Common.assertAsString(error.message);
//        }
//        return null;
//    }
    public static Map<String,String> getSts() {
        OssConfig ossConfig = SpringUtil.getBean(OssConfig.class);
        OSS ossClient = getClient();
        // host的格式为 bucketname.endpoint
        String host = "https://" + bucket + "." + ossConfig.getEndpoint();
        //上传的目录 以每天的日期为单位分目录
        String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
//        String dir = format + "/";

        Map<String, String> respMap = null;
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            // PostObject请求最大可支持的文件大小为5 GB，即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 2 * 1024 * 1024);
//            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            respMap = new LinkedHashMap<String, String>();
            respMap.put("accesskeyId", ossConfig.getKeyId());
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
//            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));

        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return respMap;
    }


}
