package com.jeequan.jeepay.components.oss.service;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.PolicyConditions;
import com.jeequan.jeepay.components.oss.constant.OssSavePlaceEnum;
import com.jeequan.jeepay.components.oss.model.OssFileConfig;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.DBOSSConfig;
import com.jeequan.jeepay.core.service.ISysConfigService;
import com.jeequan.jeepay.core.utils.DateKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.Date;

/**
* 阿里云OSS 实现类
*
* @author terrfly
* @date 2021/7/12 18:20
*/
@Service
@Slf4j
public class AliyunOssOssService implements IOssService{

    @Autowired private ISysConfigService sysConfigService;

    public OSS getOssClient(){

        DBOSSConfig.AliyunOssConfigModel aliyunOssConfigModel = sysConfigService.getOssConfig().getAliyunOssConfigModel();

        return new OSSClientBuilder().build(aliyunOssConfigModel.getEndpoint(), aliyunOssConfigModel.getAccessKeyId(), aliyunOssConfigModel.getAccessKeySecret());
    }

    @Override
    public String upload2PreviewUrl(OssSavePlaceEnum ossSavePlaceEnum, MultipartFile multipartFile, String saveDirAndFileName) {

        try {

            DBOSSConfig.AliyunOssConfigModel aliyunOssConfigModel = sysConfigService.getOssConfig().getAliyunOssConfigModel();

            getOssClient().putObject(ossSavePlaceEnum == OssSavePlaceEnum.PUBLIC ? aliyunOssConfigModel.getPublicBucketName() : aliyunOssConfigModel.getPrivateBucketName()
                    , saveDirAndFileName, multipartFile.getInputStream());

            return genUrlHost(ossSavePlaceEnum, true, saveDirAndFileName);

        } catch (Exception e) {
           log.error("error", e);
            return null;
        }
    }

    @Override
    public IOssService.UploadFormParams genFormParams(String bizType, OssFileConfig ossFileConfig, String saveDirAndFileName) {

        try {


            DBOSSConfig.AliyunOssConfigModel aliyunOssConfigModel = sysConfigService.getOssConfig().getAliyunOssConfigModel();

            //生成Policy  Post policy 文档： https://help.aliyun.com/document_detail/31988.html?spm=a2c4g.11186623.6.1635.4dbb2e3cCqA5WM
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, ossFileConfig.getMaxSize());  //上传文件限制
            String postPolicy = getOssClient().generatePostPolicy(new Date(DateKit.currentTimeMillis() + aliyunOssConfigModel.getExpireTime()), policyConds);


            IOssService.UploadFormParams result = new UploadFormParams();
            result.setFormActionUrl(this.genUrlHost(ossFileConfig.getOssSavePlaceEnum(), true, null));  //前端请求的url地址
            result.setOssFileUrl(this.genUrlHost(ossFileConfig.getOssSavePlaceEnum(), true, saveDirAndFileName));  //当上传成功 oss响应200时， 使用该路径作为文件路径

            //返回前端form表单的参数。 文档： https://help.aliyun.com/document_detail/31988.html?spm=a2c4g.11186623.2.7.b37c436781S3Gx#reference-smp-nsw-wdb
            JSONObject formParams = new JSONObject();
            formParams.put("OSSAccessKeyId",  aliyunOssConfigModel.getAccessKeyId());  //AccessKeyId
            formParams.put("policy", BinaryUtil.toBase64String(postPolicy.getBytes("utf-8")));  //policy为一段经过UTF-8和base64编码的JSON文本
            formParams.put("Signature", getOssClient().calculatePostSignature(postPolicy));   //签名
            formParams.put("key", saveDirAndFileName);  //上传的文件名
            formParams.put("success_action_status", "200"); //上传成功响应200， 默认204
            result.setFormParams(formParams);

            return result;
        } catch (Exception e) {
            log.error("生成上传form表单数据失败", e);
            throw new BizException(e.getMessage());
        }
    }

    @Override
    public boolean downloadFile(OssSavePlaceEnum ossSavePlaceEnum, String source, String target) {

        try {

            DBOSSConfig.AliyunOssConfigModel aliyunOssConfigModel = sysConfigService.getOssConfig().getAliyunOssConfigModel();

            String bucket = ossSavePlaceEnum == OssSavePlaceEnum.PRIVATE ? aliyunOssConfigModel.getPrivateBucketName() : aliyunOssConfigModel.getPublicBucketName();
            this.getOssClient().getObject(new GetObjectRequest(bucket, source), new File(target));

            return true;
        } catch (Exception e) {
            log.error("error", e);
            return false;
        }
    }


    /** 返回请求地址 / 文件地址 **/
    public String genUrlHost(OssSavePlaceEnum ossSavePlaceEnum, boolean isHttps, String saveDirAndFileName){

            // 私有文件 && 存在下载地址 ： 返回存储地址
           if(ossSavePlaceEnum == OssSavePlaceEnum.PRIVATE && StringUtils.isNotEmpty(saveDirAndFileName)){
               return saveDirAndFileName;
           }

        DBOSSConfig.AliyunOssConfigModel aliyunOssConfigModel = sysConfigService.getOssConfig().getAliyunOssConfigModel();

        // 公共读  or  上传action

            // 文档：https://www.alibabacloud.com/help/zh/doc-detail/39607.htm  example: https://BucketName.Endpoint/ObjectName
            return
                    ( isHttps ? "https://" : "http://" )
                    + ( ossSavePlaceEnum == OssSavePlaceEnum.PUBLIC ? aliyunOssConfigModel.getPublicBucketName() : aliyunOssConfigModel.getPrivateBucketName() )
                    + "." + aliyunOssConfigModel.getEndpoint() + "/" + StringUtils.defaultIfEmpty(saveDirAndFileName, "");
    }

}
