package com.yunfeiyun.agmp.common.framework.oss.cloud;

import com.aliyun.oss.*;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.yunfeiyun.agmp.common.exception.OssFileUploadException;
import com.yunfeiyun.agmp.common.framework.config.properties.OSSProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 阿里云OSS存储
 *
 * @author 杨晓辉
 */
public class AliyunCloudStorageService extends AbstractCloudStorageService {

    private static final Logger log = LoggerFactory.getLogger(AliyunCloudStorageService.class);

    public AliyunCloudStorageService(OSSProperties config){
        this.config = config;
    }

    @Override
    public String upload(byte[] data, String path) {
        return upload(new ByteArrayInputStream(data), path);
    }

    @Override
    public String upload(InputStream inputStream, String path) {
        //ClientConfiguration ossClientConf = new ClientConfiguration();
        //ossClientConf.setConnectionTimeout(10000);
        OSSClient client = new OSSClient(config.getOssCloud().getAliYun().getAliyunEndPoint(), config.getOssCloud().getAliYun().getAliyunAccessKeyId(), config.getOssCloud().getAliYun().getAliyunAccessKeySecret());
        try {
            client.putObject(config.getOssCloud().getAliYun().getAliyunBucketName(), path, inputStream);
        } catch (Exception e){
            e.printStackTrace();
            throw new OssFileUploadException(path,path, path);
        }finally {
            client.shutdown();
        }
        return config.getOssCloud().getAliYun().getAliyunDomain() + "/" + path;
    }

    @Override
    public String uploadSuffix(byte[] data, String suffix, String bizType,String baseName) {
        return upload(data, getPath(config.getOssCloud().getAliYun().getAliyunPrefix(), suffix , bizType,baseName));
    }

    @Override
    public String uploadSuffix(InputStream inputStream, String suffix,String bizType,String baseName) {
        return upload(inputStream, getPath(config.getOssCloud().getAliYun().getAliyunPrefix(), suffix,bizType,baseName));
    }

    @Override
    public String padSuffix(String resOssUrl){
        return resOssUrl.substring(config.getOssCloud().getAliYun().getAliyunDomain().length() + 1);
    }

    /**
     * 文件删除
     * @param resOssUrl
     */
    @Override
    public  List<String> delete(List<String> resOssUrl) {
        OSSClient client = null;
        try{
            resOssUrl = resOssUrl.stream().map(v->{ return padSuffix(v); }).collect(Collectors.toList());
            OSS ossClient = new OSSClientBuilder().build(config.getOssCloud().getAliYun().getAliyunEndPoint(), config.getOssCloud().getAliYun().getAliyunAccessKeyId(), config.getOssCloud().getAliYun().getAliyunAccessKeySecret());
            //CredentialsProvider credentialsProvider = new DefaultCredentialProvider(config.getOssCloud().getAliYun().getAliyunAccessKeyId(), config.getOssCloud().getAliYun().getAliyunAccessKeySecret());
            DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(config.getOssCloud().getAliYun().getAliyunBucketName()).withKeys(resOssUrl));
            List<String> urls = deleteObjectsResult.getDeletedObjects();
            for (String object : urls) {
                log.info("OSS删除文件:[{}] requestId=[{}] " , object , deleteObjectsResult.getRequestId());
            }
            return urls;
        }catch (OSSException oe) {
            log.info("OSS 错误信息: " + oe.getErrorCode());
            log.info("OSS 错误码: :    " + oe.getErrorCode());
            log.info("请求ID:    " + oe.getRequestId());
            log.info("主机ID:       " + oe.getHostId());
        } catch (ClientException ce) {
            log.info("消息错误: " + ce.getMessage());
        }catch (Exception ce) {
            log.info("消息错误: " + ce.getMessage());
        }finally {
           if(client != null) client.shutdown();
        }
        return new ArrayList<>();
    }


    /**
     * 删除文件或目录
     *
     * @param objectName 填写文件完整路径。文件完整路径中不能包含Bucket名称。
     */
    public  Boolean deleteFile(String objectName) {
        OSS ossClient = new OSSClientBuilder().build(config.getOssCloud().getAliYun().getAliyunEndPoint(), config.getOssCloud().getAliYun().getAliyunAccessKeyId(), config.getOssCloud().getAliYun().getAliyunAccessKeySecret());
        ossClient.shutdown();
        boolean flag = false;
        try {
            boolean success = ossClient.doesObjectExist(config.getOssCloud().getAliYun().getAliyunBucketName() ,  objectName);
            if(!success){
                log.info("OSS文件:[  {}  ]   不存在" ,objectName);
                return false;
            }
            // 删除文件或目录。如果要删除目录，目录必须为空。
            ossClient.deleteObject(config.getOssCloud().getAliYun().getAliyunBucketName(), objectName);
            flag = true;
        } catch (OSSException oe) {
            log.error("请求已发送到OSS,但由于某种原因被拒绝并出现错误响应");
            log.error("Error Message:[{}]", oe.getErrorMessage());
            log.error("Error Code:[{}]", oe.getErrorCode());
            log.error("Request ID:[{}]", oe.getRequestId());
            log.error("Host ID:[{}]", oe.getHostId());
        } catch (ClientException ce) {
            log.error("客户端在尝试与OSS通信时遇到问题");
            log.error("Error Message:[{}]", ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return flag;
    }

}