package com.cf.imes.framework.es.config;

import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import com.cf.imes.framework.es.core.service.ESDocumentService;
import com.cf.imes.framework.es.core.service.ESDocumentServiceImpl;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.util.StringUtils;


/**
 * @author there
 */
@AutoConfiguration
@ConditionalOnClass(ElasticsearchClient.class)
@EnableConfigurationProperties(EsProperties.class)
public class ChenfengElasticsearchAutoConfiguration {

    //超时时间设置
    public static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = 10000;
    public static final int DEFAULT_SOCKET_TIMEOUT_MILLIS = 300000;
    public static final int DEFAULT_CONNECT_REQUEST_TIMEOUT_MILLIS = 1000;

    /**
     * 同步方式
     *
     */
    @Bean
    public ElasticsearchClient elasticsearchClient(EsProperties properties) {
        return new ElasticsearchClient(getTransport(properties.getUris()));
    }

    /**
     * 异步方式
     *
     */
    @Bean
    public ElasticsearchAsyncClient elasticsearchAsyncClient(EsProperties properties) {
        return new ElasticsearchAsyncClient(getTransport(properties.getUris()));
    }


    @Bean
    private ESDocumentService esDocumentService(ElasticsearchClient elasticsearchClient, ElasticsearchAsyncClient elasticsearchAsyncClient) {
        return new ESDocumentServiceImpl(elasticsearchClient, elasticsearchAsyncClient);
    }

    /**
     * 获取客户端 RestClientTransport
     */
    private RestClientTransport getTransport(String hosts){
        HttpHost[] httpHosts = toHttpHost(hosts);
        RestClient restClient = getRestClient(httpHosts);
        return new RestClientTransport(restClient, new JacksonJsonpMapper());
    }

    /**
     * 获取客户端RestClient
     * @param httpHosts http数组
     */
    private RestClient getRestClient(HttpHost[] httpHosts){
        return RestClient.builder(httpHosts).setRequestConfigCallback(requestConfigBuilder -> {
            requestConfigBuilder.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT_MILLIS);
            requestConfigBuilder.setSocketTimeout(DEFAULT_SOCKET_TIMEOUT_MILLIS);
            requestConfigBuilder.setConnectionRequestTimeout(DEFAULT_CONNECT_REQUEST_TIMEOUT_MILLIS);
            return requestConfigBuilder;
        }).build();
    }

    /**
     * 解析配置的字符串hosts，转为HttpHost对象数组
     */
    private HttpHost[] toHttpHost(String hosts) {
        if (!StringUtils.hasLength(hosts)) {
            throw new RuntimeException("invalid elasticsearch configuration. elasticsearch.hosts不能为空！");
        }
        // 多个IP逗号隔开
        String[] hostArray = hosts.split(",");
        HttpHost[] httpHosts = new HttpHost[hostArray.length];
        HttpHost httpHost;
        for (int i = 0; i < hostArray.length; i++) {
            String[] strings = hostArray[i].split(":");
            httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
            httpHosts[i] = httpHost;
        }

        return httpHosts;
    }




}
