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

import cn.reghao.tnb.search.esapp.config.AppProperties;
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;
    private final ElasticsearchAsyncClient asyncClient;

    public ElasticService(AppProperties appProperties) {
        String host = appProperties.getEsHost();
        int port = appProperties.getEsPort();
        String username = appProperties.getEsUsername();
        String password = appProperties.getEsPassword();
        this.esClient = getElasticsearchClient(host, port, username, password);
        this.asyncClient = getElasticsearchAsyncClient(host, port, username, password);
    }

    private ElasticsearchTransport getElasticsearchTransport(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());
        return transport;
    }

    private ElasticsearchClient getElasticsearchClient(String host, int port, String username, String password) {
        ElasticsearchTransport transport = getElasticsearchTransport(host, port, username, password);
        // 得到一个 es 客户端
        ElasticsearchClient client = new ElasticsearchClient(transport);
        return client;
    }

    private ElasticsearchAsyncClient getElasticsearchAsyncClient(String host, int port, String username, String password) {
        ElasticsearchTransport transport = getElasticsearchTransport(host, port, username, password);
        //得到一个 es 异步客户端
        ElasticsearchAsyncClient client = new ElasticsearchAsyncClient(transport);
        return client;
    }

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

    public ElasticsearchAsyncClient getElasticsearchAsyncClient() {
        return this.asyncClient;
    }

    public void close() {
    }
}
