package com.elab.es.client.configuration;

import com.elab.es.client.DefaultElasticSearchTemplate;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
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.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.zxp.esclientrhl.config.ElasticsearchProperties;
import org.zxp.esclientrhl.index.ElasticsearchIndexImpl;

/**
 * es的配置类
 *
 * @author ： liukx
 * @time ： 2019/8/6 - 15:48
 */
@Configuration
@ComponentScan(basePackages = {"com.elab.es.*"})
@Import({ElasticsearchIndexImpl.class})
@EnableConfigurationProperties(value = ElabESProperties.class)
public class ESConfiguration {

    @Bean
    @ConditionalOnProperty(prefix = "elab.es", name = "uris")
    public ElasticsearchProperties elasticsearchProperties(@Autowired ElabESProperties properties) {
        ElasticsearchProperties elasticsearchProperties = new ElasticsearchProperties();
        elasticsearchProperties.setHost(properties.getUris().get(0));
        elasticsearchProperties.setUsername(properties.getUsername());
        elasticsearchProperties.setPassword(properties.getPassword());
        return elasticsearchProperties;
    }

    @Bean
    public DefaultElasticSearchTemplate elasticSearchTemplate(){
        return new DefaultElasticSearchTemplate();
    }

    @Bean
    @ConditionalOnProperty(prefix = "elab.es", name = "uris")
    public RestHighLevelClient restHighLevelClient(@Autowired ElabESProperties properties) throws Exception {
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        //访问用户名和密码为您创建阿里云Elasticsearch实例时设置的用户名和密码，也是Kibana控制台的登录用户名和密码。
        if (properties.getUsername() != null && properties.getPassword() != null) {
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(properties.getUsername(), properties.getPassword()));
        }
        // 通过builder创建rest client，配置http client的HttpClientConfigCallback。
        // 单击所创建的Elasticsearch实例ID，在基本信息页面获取公网地址，即为ES集群地址。
        if (properties.getUris().size() == 1) {
            String[] urlInfo = properties.getUris().get(0).split(":");
            RestClientBuilder builder = RestClient.builder(new HttpHost(urlInfo[0], Integer.valueOf(urlInfo[1])))
                    .setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
                        @Override
                        public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
                            httpClientBuilder.setKeepAliveStrategy(getConnectionKeepAliveStrategy());
                            return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
                        }
                    });
            // RestHighLevelClient实例通过REST low-level client builder进行构造。
            RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
            return restHighLevelClient;
        } else if (properties.getUris().size() > 1) {
            throw new Exception("bucket type is not support");
        }
        throw new Exception("RestHighLevelClient 需要指定URL。yaml配置中elab.elasticsearch.uris ..");
    }
    private ConnectionKeepAliveStrategy getConnectionKeepAliveStrategy() {
        return (response, context) -> {
            return 2 * 60 * 1000;
        };
    }


}
