package com.yeejoin.amos.boot.module.common.api.config;

import org.apache.http.HttpHost;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;

@Configuration
public class ElasticSearchClientConfig {

    @Value("${spring.elasticsearch.rest.uris}")
    private String uris;
    @Value("${elasticsearch.username}")
    private String username;

    @Value("${elasticsearch.password}")
    private String password;

    @Bean(destroyMethod = "close")
    public RestHighLevelClient restHighLevelClient() {
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));

        try {
            HttpHost[] httpHosts = Arrays.stream(uris.split(",")).map(HttpHost::create).toArray(HttpHost[]::new);
            RestClientBuilder builder = RestClient.builder(httpHosts);
            // 全局HTTP客户端配置
            builder.setHttpClientConfigCallback(httpClientBuilder -> {
                httpClientBuilder.addInterceptorFirst((HttpRequestInterceptor) (request, context) -> {
                    String auth = username + ":" + password;
                    String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
                    request.setHeader("Authorization", "Basic " + encodedAuth);
                });
                return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
                        .setMaxConnTotal(200)
                        .setMaxConnPerRoute(60);
            });
            // 请求级参数配置
            builder.setRequestConfigCallback(requestConfigBuilder -> {
                return requestConfigBuilder
                        .setConnectTimeout(5000 * 1000) // 连接超时毫秒
                        .setSocketTimeout(6000 * 1000); // 读取超时毫秒
            });

            return new RestHighLevelClient(builder);
        } catch (Exception e) {
            throw new IllegalStateException("Invalid ES nodes " + "property '" + uris + "'", e);
        }
    }
}
