/**
 *
 */
package com.arms.config;

import com.arms.egovframework.javaservice.esframework.custom.client.CustomOpenSearchRestTemplate;
import com.arms.egovframework.javaservice.esframework.repository.common.EsCommonRepositoryImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.opensearch.client.RestHighLevelClient;
import org.opensearch.data.client.orhlc.AbstractOpenSearchConfiguration;
import org.opensearch.data.client.orhlc.ClientConfiguration;
import org.opensearch.data.client.orhlc.RestClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.RefreshPolicy;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;

import jakarta.annotation.PreDestroy;



@Slf4j
@Configuration
@EnableElasticsearchRepositories(basePackages = {"com.arms"},repositoryBaseClass = EsCommonRepositoryImpl.class)
@ComponentScan(basePackages = { "com.arms"})
public class OpensearchClientConfig extends AbstractOpenSearchConfiguration {

	private final ElasticsearchProperties properties;

	private RestHighLevelClient client;

	public OpensearchClientConfig(ElasticsearchProperties properties) {
		this.properties = properties;
	}

	@Override
	public RestHighLevelClient opensearchClient() {

		final ClientConfiguration clientConfiguration =
				ClientConfiguration
					.builder()
					.connectedTo(properties.getUrl())
					.withClientConfigurer(RestClients.RestClientConfigurationCallback.from(
							httpAsyncClientBuilder -> {
								httpAsyncClientBuilder.setKeepAliveStrategy(this.connectionKeepAliveStrategy());
								return httpAsyncClientBuilder;
							}
					))
					.withConnectTimeout(60000)
					.withSocketTimeout(60000)
				.build();

		this.client = RestClients.create(clientConfiguration).rest();
		return this.client;
	}

	@PreDestroy
	public void closeClient() {
		try {
			if (client != null) {
				client.close();
			}
		} catch (Exception e) {
			log.error("Error closing Elasticsearch client: ", e);
		}
	}

	@Override
	protected RefreshPolicy refreshPolicy() {
		return RefreshPolicy.IMMEDIATE;
	}

	@Bean(name = "keepAliveStrategy")
	public ConnectionKeepAliveStrategy connectionKeepAliveStrategy() {
		return (response, context) -> 180*1000;
	}

	@Override
	@Bean(name = {"elasticsearchOperations", "elasticsearchTemplate", "opensearchTemplate"})
	public ElasticsearchOperations elasticsearchOperations(
			ElasticsearchConverter elasticsearchConverter, RestHighLevelClient opensearchClient) {

		CustomOpenSearchRestTemplate template = new CustomOpenSearchRestTemplate(opensearchClient, elasticsearchConverter);
		template.setRefreshPolicy(refreshPolicy());

		return template;
	}
}
