package org.nextprot.api.solr.indexation.impl.solrdoc.entrydoc.integrationtest.diff;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocumentList;
import org.junit.Ignore;
import org.nextprot.api.core.service.MasterIdentifierService;
import org.nextprot.api.solr.core.impl.schema.CvSolrField;
import org.nextprot.api.solr.core.impl.schema.EntrySolrField;
import org.nextprot.api.solr.core.impl.schema.PublicationSolrField;
import org.nextprot.api.solr.indexation.impl.solrdoc.entrydoc.integrationtest.SolrBuildIntegrationTest;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Ignore
public abstract class SolrDiffTest extends SolrBuildIntegrationTest implements InitializingBean {
	
	@Autowired
	private MasterIdentifierService masterIdentifierService = null;
	protected List<String> entries = null;

	HttpSolrServer solrEntries = new HttpSolrServer("http://kant.isb-sib.ch:8983/solr/npentries1");
	HttpSolrServer solrEntriesGold = new HttpSolrServer("http://kant.isb-sib.ch:8983/solr/npentries1gold");
	HttpSolrServer solrPublications = new HttpSolrServer("http://kant.isb-sib.ch:8983/solr/nppublications1");
	HttpSolrServer solrCvs = new HttpSolrServer("http://kant.isb-sib.ch:8983/solr/npcvs1");

	private Object getValueForFieldInCurrentSolrImplementation(HttpSolrServer solrCore, String entryName, String fieldName) {

		List<Object> result = new ArrayList<>();

		try {
			SolrQuery query = new SolrQuery();
			query.setQuery("id:" + entryName);
			query.setFields(fieldName);
			QueryResponse response;
			response = solrCore.query(query);
			SolrDocumentList solrResults = response.getResults();

			for (int i = 0; i < solrResults.size(); ++i) {
				result.add(solrResults.get(i).get(fieldName));
			}
		} catch (SolrServerException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		if(result.size() == 0) return null; // Otherwise it could generate a IndexOutOfBoundsException !!
		return result.get(0); 
	}
	
	protected Object getValueForFieldInCurrentGoldSolrImplementation(String entryName, EntrySolrField field) {
		return getValueForFieldInCurrentSolrImplementation(solrEntriesGold, entryName, field.getName());
	}

	protected Object getValueForFieldInCurrentSolrImplementation(String entryName, EntrySolrField field) {
		return getValueForFieldInCurrentSolrImplementation(solrEntries, entryName, field.getName());
	}

	protected Object getValueForFieldInCurrentSolrImplementation(String entryName, PublicationSolrField field) {
		return getValueForFieldInCurrentSolrImplementation(solrPublications, entryName, field.getName());
	}

	protected Object getValueForFieldInCurrentSolrImplementation(String entryName, CvSolrField field) {
		return getValueForFieldInCurrentSolrImplementation(solrCvs, entryName, field.getName());
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		entries = new ArrayList<>(masterIdentifierService.findUniqueNames());
	}

	
	public int getEntriesCount() {
		return entries.size();
	}

	/**
	 * Utility to parse html-like lines generated by current Solr implementation
	 * It removes all other elements, example:
	 * 
	 * 
	 * <b>anno_name : </b>mature protein <b>anno_qualname : </b>GOLD
	 * <b>description : </b>Putative uncharacterized protein HSD52
	 * <b>an_synonyms : </b>PRO_0000342680 <b>anno_name : </b>uniprot keyword
	 * <b>anno_qualname : </b>GOLD <b>description : </b>Complete proteome
	 * <b>cv_ancestors_acs : </b>KW-0181 <b>cv_ac : </b>KW-0181 <b>cv_name :
	 * </b>Complete proteome
	 */

	public static String getValueFromRawData(String html, String subfield) {
		String aux = "";
		aux = html.replaceAll("<p>|</p>", "");
		String[] btags = aux.split("<b>");
		for (String bt : btags) {
			if (bt.startsWith(subfield)) {
				return bt.substring(bt.indexOf("</b>") + 4);
			}
		}
		return null;
	}

	public static <T> T getFieldValue(Map<EntrySolrField, Object> fields, EntrySolrField field, Class<T> requiredType) {

		if (fields.containsKey(field)) {
			return requiredType.cast(fields.get(field));
		}
		return null;
	}
}
