/**
 * Copyright (c) 2025 SoftCorporation LLC. All rights reserved.
 *
 * The Software License, Version 1.0
 *
 * SoftCorporation LLC. grants you ("Licensee") a non-exclusive, royalty free,
 * license to use, modify and redistribute this software in source and binary
 * code form, provided that the following conditions are met:
 *
 * 1. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        SoftCorporation LLC. (http://www.softcorporation.com)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 2. This software and SoftCorporation name must not be used to
 *    promote products derived from the software without prior
 *    written permission. For written permission, please contact
 *    info@softcorporation.com.
 *
 * This software is provided "AS IS," without a warranty of any kind.
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
 * IN NO EVENT SHALL THE SOFTCORPORATION BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION).
 *
 */
package com.softcorporation.sandi.base.service.solr;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.Http2SolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.common.SolrDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class SolrService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SolrService.class);

    @Value("${sandi.solr.zookeeper.hosts:localhost:2181}")
    private String zookeeperHosts;

    /**
     * String user.
     */
    @Value("${sandi.solr.username:}")
    private String username;

    /**
     * String password.
     */
    @Value("${sandi.solr.password:}")
    private String password;
    
    /**
     * Connection Timeout in ms.
     */
    @Value("${sandi.solr.connection.timeout:10000}")
    private int connectionTimeout;

    /**
     * Socket Timeout in ms.
     */
    @Value("${sandi.solr.socket.timeout:60000}")
    private int socketTimeout;

    /**
     * Solr Client
     */
    private SolrClient solrClient;

    @PostConstruct
    public void init() {
        LOGGER.info("Initializing SolrService with ZooKeeper hosts: {}", zookeeperHosts);
        LOGGER.debug("Connection timeout: {}ms, Socket timeout: {}ms", connectionTimeout, socketTimeout);
        
        List<String> zkHosts = Arrays.asList(zookeeperHosts.split(","));
        
        try {
        	Http2SolrClient httpClient;
        	if (!password.isEmpty()) {
                httpClient = new Http2SolrClient.Builder()
                        .withBasicAuthCredentials(username, password)
                        .build();
        	} else {
                httpClient = new Http2SolrClient.Builder().build();
        	}
        	
//        	solrClient = new HttpSolrClient.Builder("http://localhost:8983/solr")
//                    .withConnectionTimeout(connectionTimeout)
//                    .withSocketTimeout(socketTimeout)
//                    .build();
        	
        	solrClient = new CloudSolrClient.Builder(zkHosts, Optional.empty())
                    .withZkConnectTimeout(connectionTimeout, TimeUnit.MILLISECONDS)
                    .withZkClientTimeout(socketTimeout, TimeUnit.MILLISECONDS)
                    .withHttpClient(httpClient)
                    .build();
            
            LOGGER.info("CloudSolrClient initialized successfully with ZooKeeper hosts: {}", zookeeperHosts);
        } catch (Exception e) {
            LOGGER.error("Failed to initialize CloudSolrClient: {}", e.getMessage(), e);
            throw e;
        }
    }

    /**
     * Get Solr Client
     */
    public synchronized SolrClient getSolrClient() {
        return solrClient;
    }

    protected String getString(SolrDocument doc, String field) {
        Object value = doc.getFieldValue(field);
        if (value == null) {
        	return null;
        }
//        if (value instanceof List && ((List) value).size() == 1) {
//        	value = ((List) value).get(0);
//        }
        return value.toString();
    }

    protected Integer getInteger(SolrDocument doc, String field) {
        Object value = doc.getFieldValue(field);
        if (value instanceof Integer) {
            return (Integer) value;
        } else if (value instanceof String) {
            try {
                return Integer.parseInt((String) value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    @PreDestroy
    public void close() {
        if (solrClient != null) {
            try {
                LOGGER.debug("Closing CloudSolrClient connection");
                solrClient.close();
                LOGGER.info("CloudSolrClient closed successfully");
            } catch (IOException e) {
                LOGGER.error("Error closing CloudSolrClient: {}", e.getMessage(), e);
            }
        }
    }
    
    /**
     * Reset the solr client.
     */
    public synchronized void reset() {
        close();
        init();
    }

}

