package com.chushang.oss.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.aliyun.oss.model.Payer;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chushang.common.core.exception.ResultException;
import com.chushang.common.core.util.StringUtils;
import com.chushang.oss.config.UploadConfig;
import com.chushang.oss.entity.FileSourceInfo;
import com.chushang.oss.mapper.FileSourceMapper;
import com.chushang.oss.service.OssService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 阿里云存储
 */
@Slf4j
@Service("aliOssService")
@ConditionalOnExpression("'${oss.storage}'.equals('ali')")
public class AliServiceImpl implements OssService {

    private OSS oss;

    @Resource
    private UploadConfig config;

//    public AliyunUploadStorageService(CloudProperties cloudProperties){
//        this.config = (AliyunProperties) cloudProperties;
//        //初始化
//        init();
//    }

    @PostConstruct
    private void init(){
        oss = new OSSClientBuilder()
                        .build(config.getEndPoint(), config.getAccessKey(), config.getSecretKey());
        Payer payer = Payer.Requester;
        oss.setBucketRequestPayment(config.getBucketName(), payer);
    }

    @Override
    public String upload(byte[] data, String path) {
        String aliyunPrefix = config.getPrefix();
        if (StringUtils.isNotEmpty(aliyunPrefix)){
            path = aliyunPrefix + "/" + path;
        }
        return upload(new ByteArrayInputStream(data), path);
    }

    /**
     * path
     * @param inputStream   字节流
     * @param path          文件路径，包含文件名
     */
    @Override
    public String upload(InputStream inputStream, String path) {
        try {
            oss.putObject(config.getBucketName(), path, inputStream);
        } catch (Exception e){
            throw new ResultException("上传文件失败，请检查配置信息", e);
        }

        return UploadConfig.getDomain() + "/" + path;
    }

    @Override
    public String uploadSuffix(byte[] data, String suffix) {
        return upload(data, getSuffixPath(suffix));
    }

    @Override
    public String uploadSuffix(byte[] data, String suffix, String filename) {
        return upload(data, getSuffixPath(suffix, filename));
    }

    @Override
    public String uploadPrefix(byte[] data, String prefix, String suffix, String filename) {
        return upload(data, getSuffixPath(prefix, suffix, filename));
    }

    @Override
    public String uploadPrefix(byte[] data, String prefix, String filename) {
        return upload(data, getPrefixPath(prefix, filename));
    }

    @Override
    public String uploadSuffix(InputStream inputStream, String suffix) {
        return upload(inputStream, getSuffixPath(suffix));
    }

    @Override
    public void delFile(String path){
        try {
            oss.deleteObject(config.getBucketName(), path);
        } catch (Exception e){
            throw new ResultException("删除文件失败，请检查配置信息", e);
        }
    }

    public List<String> delFileBatch(List<String> keys){
        try {
            // 批量删除
            DeleteObjectsRequest objectsRequest = new DeleteObjectsRequest(config.getBucketName());

            objectsRequest.setKeys(keys);
            objectsRequest.setQuiet(true);
            objectsRequest.setEncodingType("url");

            DeleteObjectsResult deleteObjectsResult = oss.deleteObjects(objectsRequest);
            List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
            if (CollectionUtil.isNotEmpty(deletedObjects)){
                log.error("以下文件未从oss 中成功删除 : {}", deletedObjects);
                return deletedObjects;
            }
        } catch (Exception e){
            throw new ResultException("删除文件失败，请检查配置信息", e);
        }
        return new ArrayList<>();
    }

}

