package com.xingxi.common.aliyun.oss;

import com.aliyun.oss.OSS;
import com.aliyun.oss.internal.OSSConstants;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.InputStream;

@Slf4j
@Component
public class DefaultAliyunOSSClient implements AliyunOSSClient {
    @Resource
    private OSS ossClient;

    @Value("${aliyun.oss.bucketName}")
    private String bucketName;

    @Value("${aliyun.oss.customDomain}")
    private String customDomain;

    /**
     * 桶子如果不存在就创建
     *
     * @param bucketName
     * @throws Exception
     */
    @Override
    public void createBucket(String bucketName) throws Exception {
        if (!ossClient.doesBucketExist(bucketName)) {
            ossClient.createBucket(bucketName);
        }
    }

    /**
     * 上传文件到指定桶子,默认公共读取
     *
     * @param bucketName
     * @param objectName
     * @param inputStream
     * @return
     * @throws Exception
     */
    @Override
    public String putObject(String bucketName, String objectName, InputStream inputStream) throws Exception {
        return putObject(bucketName, objectName, inputStream, CannedAccessControlList.PublicRead);
    }

    /**
     * 上传文件
     *
     * @param bucketName
     * @param objectName
     * @param inputStream
     * @param cannedAccessControlList
     * @return
     * @throws Exception
     */
    @Override
    public String putObject(String bucketName, String objectName, InputStream inputStream, CannedAccessControlList cannedAccessControlList) throws Exception {

        log.info("OSS上传文件,bucketName={},objectName={},ObjectAcl={}", bucketName, objectName, cannedAccessControlList);
        // 创建桶子
        createBucket(bucketName);

        PutObjectResult putObjectResult = null;
        try {
            // 上传文件
            putObjectResult = ossClient.putObject(bucketName, objectName, inputStream);
            // 设置文件Acl权限
            ossClient.setObjectAcl(bucketName, objectName, cannedAccessControlList);
        } finally {

            if (putObjectResult != null && putObjectResult.getResponse() != null) {
                putObjectResult.getResponse().close();
            }

            if (inputStream != null) {
                inputStream.close();
            }
        }

        // 构建返回url
        String url = OSSConstants.PROTOCOL_HTTPS + bucketName + "." + getProfile().getEndPoint() + "/" + objectName;
        // 如果自定义域名
        if (getProfile().getCustomDomain() != null) {
            // 转换自定义域名
            url = OSSConstants.PROTOCOL_HTTPS + getProfile().getCustomDomain() + "/" + objectName;
        }

        log.info("URL=[{}]", url);
        // 返回
        return url;

    }

    /**
     * 上传文件到默认桶子
     *
     * @param objectName
     * @param inputStream
     * @return
     * @throws Exception
     */
    @Override
    public String putObject(String objectName, InputStream inputStream) throws Exception {
        return putObject(getProfile().getBucketName(), objectName, inputStream);
    }


    /**
     * 默认上传default bucket
     *
     * @param objectName
     * @param inputStream
     * @param cannedAccessControlList
     * @return
     * @throws Exception
     */
    @Override
    public String putObject(String objectName, InputStream inputStream, CannedAccessControlList cannedAccessControlList) throws Exception {
        return putObject(getProfile().getBucketName(), objectName, inputStream, cannedAccessControlList);
    }

    /**
     * 取得指定桶子中的文件
     *
     * @param bucketName
     * @param objectName
     * @return
     */
    @Override
    public OSSObject getObject(String bucketName, String objectName) {
        log.info("获取oss文件,bucketName={},objectName={}", bucketName, objectName);
        if (ossClient.doesObjectExist(bucketName, objectName)) {
            return ossClient.getObject(bucketName, objectName);
        }
        return null;
    }

    @Override
    public boolean doesObjectExist(String objectName) throws Exception {
        return ossClient.doesObjectExist(bucketName, objectName);
    }

    /**
     * 取得默认桶子中的文件
     *
     * @param objectName
     * @return
     * @throws Exception
     */
    @Override
    public OSSObject getObject(String objectName) throws Exception {
        return getObject(getProfile().getBucketName(), objectName);
    }

    /**
     * 删除指定桶子中的文件
     *
     * @param bucketName
     * @param objectName
     * @throws Exception
     */
    @Override
    public void removeObject(String bucketName, String objectName) throws Exception {
        if (ossClient.doesObjectExist(bucketName, objectName)) {
            ossClient.deleteObject(bucketName, objectName);
        }
    }

    /**
     * 取得配置文件信息
     *
     * @return
     */
    @Override
    public AliyunOSSProfile getProfile() {
        return new AliyunOSSProfile() {
            @Override
            public String getEndPoint() {
                return null;
            }

            @Override
            public String getAccessKeyID() {
                return null;
            }

            @Override
            public String getAccessKeySecret() {
                return null;
            }

            @Override
            public String getBucketName() {
                return bucketName;
            }

            @Override
            public String getCustomDomain() {
                return customDomain;
            }
        };
    }
}
