package cn.reghao.tnb.search.app.es;

import cn.reghao.tnb.search.app.config.ElasticProperties;
import co.elastic.clients.elasticsearch.ElasticsearchAsyncClient;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
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.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author reghao
 * @date 2025-03-12 10:41:52
 */
@Service
public class ElasticService {
    private final ElasticsearchClient esClient;

    public ElasticService(ElasticProperties elasticProperties) {
        String host = elasticProperties.getHost();
        int port = elasticProperties.getPort();
        String username = elasticProperties.getUsername();
        String password = elasticProperties.getPassword();
        this.esClient = getElasticsearchClient(host, port, username, password);
    }

    private ElasticsearchClient getElasticsearchClient(String host, int port, String username, String password) {
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));

        // 创建 SSL 上下文
        /*SSLContextBuilder sslBuilder = SSLContexts.custom().loadTrustMaterial(null, (chain, authType) -> true);
        final SSLContext sslContext = sslBuilder.build();*/

        HttpHost httpHost = new HttpHost(host, port);
        // 创建 low-level client
        RestClientBuilder builder = RestClient.builder(httpHost)
                .setHttpClientConfigCallback(httpClientBuilder ->
                        httpClientBuilder
                                // 超时 10 分钟
                                .setConnectionTimeToLive(600, TimeUnit.SECONDS)
                                .setDefaultCredentialsProvider(credentialsProvider))
                                /*.setSSLContext(sslContext)
                                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE))*/;
        RestClient restClient = builder.build();

        // 创建一个 Transport 通信和一个 JacksonJsonpMapper 序列化实例
        ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
        // 得到一个 es 客户端
        ElasticsearchClient client = new ElasticsearchClient(transport);
        return client;
    }

    private ElasticsearchAsyncClient getElasticsearchAsyncClient(String host, int port) {
        //创建 low-level client
        RestClient restClient = RestClient.builder(new HttpHost(host, port)).build();
        //创建一个Transport通信 和 一个JacksonJsonpMapper序列化实例
        ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());

        //得到一个es客户端
        ElasticsearchAsyncClient client = new ElasticsearchAsyncClient(transport);
        return client;
    }

    public ElasticsearchClient getElasticsearchClient() {
        return this.esClient;
    }

    public void close() {
    }
}
