package com.schisandra.oss.application.oss.core.ali;

import cn.hutool.core.text.CharPool;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;

import com.aliyun.oss.common.comm.Protocol;
import com.schisandra.oss.application.convert.SchisandraOssAliDTOConverter;
import com.schisandra.oss.application.dto.SchisandraOssAliDTO;
import com.schisandra.oss.application.dto.SchisandraOssMinioDTO;
import com.schisandra.oss.application.oss.constant.OssConstant;
import com.schisandra.oss.application.oss.core.StandardOssClient;
import com.schisandra.oss.application.oss.core.ali.model.AliOssClientConfig;
import com.schisandra.oss.application.oss.core.ali.model.AliOssConfig;
import com.schisandra.oss.application.oss.core.minio.MinioOssClient;
import com.schisandra.oss.domain.bo.SchisandraOssAliBO;
import com.schisandra.oss.domain.service.SchisandraOssAliDomainService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;

/**
 * @author landaiqing
 * @version AliOssConfiguration.java, v 1.1 2021/11/16 15:25 chenmin Exp $
 * Created on 2021/11/16
 */
@Component
@Slf4j
public class AliOssConfiguration {

    @Resource
    SchisandraOssAliDomainService schisandraOssAliDomainService;
    @Resource
    AliOssClient aliOssClient;

    public StandardOssClient aliOssClient(String userId) {
        CompletableFuture<SchisandraOssAliDTO> futurePrice = CompletableFuture.supplyAsync(() -> {
            SchisandraOssAliBO schisandraOssAliBO = schisandraOssAliDomainService.getAliOssConfig(Long.valueOf(userId));
            SchisandraOssAliDTO schisandraOssAliDTO = SchisandraOssAliDTOConverter.INSTANCE.convertBOToDTO(schisandraOssAliBO);
            return schisandraOssAliDTO;
        });
        SchisandraOssAliDTO ali = futurePrice.join();
        if (ObjectUtils.isEmpty(ali)) {
            log.error("ali oss配置信息获取失败");
            return null;
        }
        AliOssConfig aliOssConfig = new AliOssConfig();
        aliOssConfig.setEndpoint(ali.getEndpoint());
        aliOssConfig.setAccessKeyId(ali.getAccessKeyId());
        aliOssConfig.setAccessKeySecret(ali.getAccessKeySecret());
        aliOssConfig.setSecurityToken(ali.getSecurityToken());
        if (Boolean.parseBoolean(ali.getOpenAdvancedSetup())) {
            AliOssClientConfig aliOssClientConfig = new AliOssClientConfig();
            aliOssClientConfig.setCnameExcludeList(Arrays.asList(Optional.ofNullable(ali.getCnameExcludeList()).orElse("").split(",")));
            aliOssClientConfig.setConnectionTimeout(ali.getConnectionTimeout());
            aliOssClientConfig.setConnectionTTL(ali.getConnectionTTL());
            aliOssClientConfig.setProtocol(Protocol.valueOf(ali.getProtocol()));
            aliOssClientConfig.setConnectionRequestTimeout(ali.getConnectionRequestTimeout());
            aliOssClientConfig.setMaxConnections(ali.getMaxConnections());
            aliOssClientConfig.setProxyPort(Integer.parseInt(ali.getProxyPort()));
            aliOssClientConfig.setProxyDomain(ali.getProxyDomain());
            aliOssClientConfig.setCrcCheckEnabled(Boolean.parseBoolean(ali.getCrcCheckEnabled()));
            aliOssClientConfig.setTickOffset(ali.getTickOffset());
            aliOssClientConfig.setProxyHost(ali.getProxyHost());
            aliOssClientConfig.setProxyPassword(ali.getProxyPassword());
            aliOssClientConfig.setProxyUsername(ali.getProxyUsername());
            aliOssClientConfig.setVerifySSLEnable(Boolean.parseBoolean(ali.getVerifySSLEnable()));
            aliOssClientConfig.setUseSystemPropertyValues(Boolean.parseBoolean(ali.getUseSystemPropertyValues()));
            aliOssClientConfig.setUseReaper(Boolean.parseBoolean(ali.getUseReaper()));
            aliOssClientConfig.setSupportCname(Boolean.parseBoolean(ali.getSupportCname()));
            aliOssClientConfig.setSocketTimeout(ali.getSocketTimeout());
            aliOssClientConfig.setSldEnabled(Boolean.parseBoolean(ali.getSldEnabled()));
            aliOssClientConfig.setProxyWorkstation(ali.getProxyWorkstation());
            aliOssClientConfig.setIdleConnectionTime(ali.getIdleConnectionTime());
            aliOssClientConfig.setLogConnectionPoolStats(Boolean.parseBoolean(ali.getLogConnectionPoolStats()));
            aliOssConfig.setClientConfig(aliOssClientConfig);
        }
        return aliOssClient(aliOssConfig);
    }

    public StandardOssClient aliOssClient(AliOssConfig aliOssConfig) {
        aliOssClient.setAliOssConfig(aliOssConfig);
        aliOssClient.setOss(ossClient(aliOssConfig));
        return aliOssClient;
    }

    public OSS ossClient(AliOssConfig aliOssConfig) {
        String securityToken = aliOssConfig.getSecurityToken();
        AliOssClientConfig clientConfiguration = aliOssConfig.getClientConfig();
        if (ObjectUtil.isEmpty(securityToken) && ObjectUtil.isNotEmpty(clientConfiguration)) {
            return new OSSClientBuilder().build(aliOssConfig.getEndpoint(),
                    aliOssConfig.getAccessKeyId(),
                    aliOssConfig.getAccessKeySecret(), clientConfiguration.toClientConfig());
        }
        if (ObjectUtil.isNotEmpty(securityToken) && ObjectUtil.isEmpty(clientConfiguration)) {
            return new OSSClientBuilder().build(aliOssConfig.getEndpoint(),
                    aliOssConfig.getAccessKeyId(),
                    aliOssConfig.getAccessKeySecret(), securityToken);
        }
        return new OSSClientBuilder().build(aliOssConfig.getEndpoint(),
                aliOssConfig.getAccessKeyId(),
                aliOssConfig.getAccessKeySecret(), securityToken,
                Optional.ofNullable(clientConfiguration).orElse(new AliOssClientConfig()).toClientConfig());
    }

}
