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

import cn.hutool.extra.spring.SpringUtil;
import com.schisandra.oss.application.convert.SchisandraOssMinioDTOConverter;
import com.schisandra.oss.application.dto.SchisandraOssMinioDTO;
import com.schisandra.oss.application.oss.core.StandardOssClient;
import com.schisandra.oss.application.oss.core.minio.model.MinioOssClientConfig;
import com.schisandra.oss.application.oss.core.minio.model.MinioOssConfig;
import com.schisandra.oss.common.entity.Result;
import com.schisandra.oss.common.redis.RedisUtil;
import com.schisandra.oss.domain.bo.SchisandraOssMinioBO;
import com.schisandra.oss.domain.service.SchisandraOssMinioDomainService;
import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author landaiqing
 * @version MinioConfiguration.java, v 1.1 2021/11/24 15:20 chenmin Exp $
 * Created on 2021/11/24
 */
@Component
@Slf4j
public class MinioOssConfiguration {

    @Resource
    private RedisUtil redisUtil;
    @Resource
    MinioOssConfiguration minioOssConfiguration;

    @Resource
    private SchisandraOssMinioDomainService schisandraOssMinioDomainService;

    public Result minioOssClient(String userId) {
        try {
            SchisandraOssMinioDTO minio = minioOssConfiguration.getSchisandraOssMinioDTO(userId);
            if (minio == null) return null;
            MinioOssConfig minioOssConfig = new MinioOssConfig();
            minioOssConfig.setBasePath(minio.getBasePath());
            minioOssConfig.setBucketName(minio.getBucketName());
            minioOssConfig.setAccessKey(minio.getAccessKey());
            minioOssConfig.setSecretKey(minio.getSecretKey());
            minioOssConfig.setEndpoint(minio.getEndpoint());
            minioOssConfig.init();
            if (Boolean.parseBoolean(minio.getOpenAdvancedSetup())) {
                MinioOssClientConfig minioOssClientConfig = new MinioOssClientConfig();
                minioOssClientConfig.setWriteTimeout(minio.getWriteTimeout());
                minioOssClientConfig.setConnectTimeout(minio.getConnectTimeout());
                minioOssClientConfig.setReadTimeout(minio.getReadTimeout());
                minioOssClientConfig.setFollowSslRedirects(Boolean.parseBoolean(minio.getFollowSslRedirects()));
                minioOssClientConfig.setRetryOnConnectionFailure(Boolean.parseBoolean(minio.getRetryOnConnectionFailure()));
                minioOssClientConfig.setPingInterval(minio.getPingInterval());
                minioOssClientConfig.setFollowRedirects(Boolean.parseBoolean(minio.getFollowRedirects()));
                minioOssClientConfig.setCallTimeout(minio.getCallTimeout());
                minioOssConfig.setClientConfig(minioOssClientConfig);
            }
            SpringUtil.registerBean(userId, minioOssClient(minioOssConfig));
            return Result.ok();
        } catch (Exception e) {
            log.error("MinioOssConfiguration.minioOssClient:{}", e.getMessage(), e);
            return Result.fail();
        }
    }


    public SchisandraOssMinioDTO getSchisandraOssMinioDTO(String userId) {
        CompletableFuture<SchisandraOssMinioDTO> futurePrice = CompletableFuture.supplyAsync(() -> {
            SchisandraOssMinioBO minioBO = schisandraOssMinioDomainService.getMinioConfig(Long.valueOf(userId));
            SchisandraOssMinioDTO minioDTO = SchisandraOssMinioDTOConverter.INSTANCE.convertBOToDTO(minioBO);
            return minioDTO;
        });
        SchisandraOssMinioDTO minio = futurePrice.join();
        if (ObjectUtils.isEmpty(minio)) {
            log.error("minio配置信息获取失败");
            return null;
        }
        return minio;
    }

    public StandardOssClient minioOssClient(MinioOssConfig minioOssConfig) {
        return new MinioOssClient(minioClient(minioOssConfig), minioOssConfig);
    }

    public MinioClient minioClient(MinioOssConfig minioOssConfig) {
        MinioOssClientConfig clientConfig = minioOssConfig.getClientConfig();
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(clientConfig.getConnectTimeout(), TimeUnit.MILLISECONDS)
                .writeTimeout(clientConfig.getWriteTimeout(), TimeUnit.MILLISECONDS)
                .readTimeout(clientConfig.getReadTimeout(), TimeUnit.MILLISECONDS)
                .callTimeout(clientConfig.getCallTimeout(), TimeUnit.MILLISECONDS)
                .followRedirects(clientConfig.isFollowRedirects())
                .followSslRedirects(clientConfig.isFollowSslRedirects())
                .retryOnConnectionFailure(clientConfig.isRetryOnConnectionFailure())
                .pingInterval(clientConfig.getPingInterval(), TimeUnit.MILLISECONDS)
                .build();
        return MinioClient.builder()
                .endpoint(minioOssConfig.getEndpoint())
                .credentials(minioOssConfig.getAccessKey(), minioOssConfig.getSecretKey())
                .httpClient(okHttpClient)
                .build();
    }

}

