package eu.dnetlib.functionality.index.client.solr;

import java.lang.reflect.Type;
import java.util.Map;

import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import eu.dnetlib.functionality.index.client.AbstractIndexClientFactory;
import eu.dnetlib.functionality.index.client.IndexClient;
import eu.dnetlib.functionality.index.client.IndexClientException;
import eu.dnetlib.functionality.index.client.IndexClientFactory;
import eu.dnetlib.functionality.index.query.SolrIndexQueryFactory;
import eu.dnetlib.functionality.index.query.SolrIndexQueryResponseFactory;
import eu.dnetlib.functionality.index.solr.cql.SolrTypeBasedCqlValueTransformerMapFactory;
import eu.dnetlib.functionality.index.utils.MetadataReference;
import eu.dnetlib.functionality.index.utils.MetadataReferenceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;

/**
 * The Class SolrIndexClientFactory.
 */
public class SolrIndexClientFactory extends AbstractIndexClientFactory implements IndexClientFactory {

	/** The id. */
	private static String ID = "id";

	/** The configuration. */
	private String configuration;

	/** The type token. */
	protected Type typeToken = new TypeToken<Map<String, String>>() {}.getType();

	/** The service properties. */
	private Map<String, String> serviceProperties;

	@Autowired
	private SolrIndexQueryFactory solrIndexQueryFactory;

	@Autowired
	private SolrIndexQueryResponseFactory solrIndexQueryResponseFactory;

	@Autowired
	private SolrTypeBasedCqlValueTransformerMapFactory tMapFactory;

	/**
	 * Inits the class.
	 *
	 * @throws IndexClientException
	 *             the index client exception
	 */
	@Override
	public void init() throws IndexClientException {
		try {
			serviceProperties = new Gson().fromJson(getConfiguration(), typeToken);
		} catch (Throwable e) {
			throw new IndexClientException("unable to parse configuration: " + getConfiguration(), e);
		}
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see IndexClientFactory#getBackendId()
	 */
	@Override
	public String getBackendId() {
		return serviceProperties.get(SolrIndexClientFactory.ID);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @throws IndexClientException
	 *
	 * @see IndexClientFactory#getClient(String, String, String)
	 */
	@Override
	public IndexClient getClient(final String format, final String layout, final String interpretation) throws IndexClientException {
		return new SolrIndexClient(format, layout, interpretation, isQueryTools.getIndexProperties(getBackendId()), solrIndexQueryFactory,
				solrIndexQueryResponseFactory, tMapFactory);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @throws IndexClientException
	 *
	 * @see IndexClientFactory#getClient(MetadataReference)
	 */
	@Override
	public IndexClient getClient(final MetadataReference mdRef) throws IndexClientException {
		return getClient(mdRef.getFormat(), mdRef.getLayout(), mdRef.getInterpretation());
	}

	@Override
	public IndexClient getClient(final String collection) throws IndexClientException {
		return getClient(MetadataReferenceFactory.decodeMetadata(collection));
	}

	/**
	 * Gets the configuration.
	 *
	 * @return the configuration
	 */
	public String getConfiguration() {
		return configuration;
	}

	/**
	 * Sets the configuration.
	 *
	 * @param configuration
	 *            the configuration
	 */
	@Required
	public void setConfiguration(final String configuration) {
		this.configuration = configuration;
	}

}
