package org.mousephenotype.cda.indexers;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mousephenotype.cda.indexers.utils.IndexerMap;
import org.mousephenotype.cda.solr.service.dto.StatisticalResultDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;

/**
 * @author jmason
 */
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = {TestConfigIndexers.class})
@TestPropertySource(locations = {"file:${user.home}/configfiles/${profile}/test.properties"})
@Transactional
public class StatisticalResultIndexerTest {

	@Autowired
	DataSource komp2DataSource;

	@Autowired
	StatisticalResultsIndexer statisticalResultIndexer;

	@PostConstruct
	void postConstruct() {
		try {

			statisticalResultIndexer.setConnection(komp2DataSource.getConnection());
			statisticalResultIndexer.setPipelineMap(IndexerMap.getImpressPipelines(komp2DataSource.getConnection()));
			statisticalResultIndexer.setProcedureMap(IndexerMap.getImpressProcedures(komp2DataSource.getConnection()));
			statisticalResultIndexer.setParameterMap(IndexerMap.getImpressParameters(komp2DataSource.getConnection()));
			statisticalResultIndexer.populateBiologicalDataMap();
			statisticalResultIndexer.populateResourceDataMap();
			statisticalResultIndexer.populateSexesMap();
			statisticalResultIndexer.populateParameterMpTermMap();
			statisticalResultIndexer.populateEmbryoSignificanceMap();

		} catch (SQLException e) {
			e.printStackTrace();
			assert (statisticalResultIndexer.getConnection() != null);
		}
	}

	@Test
	public void getEmbryoResults() throws Exception {

		List<StatisticalResultDTO> results = statisticalResultIndexer.getEmbryoResults().call();
		assert (results.size() > 100);
	}

	@Test
	public void resultsUniqueIds() throws Exception {

		List<String> ids = new ArrayList<>();
		List<Callable<List<StatisticalResultDTO>>> resultGenerators = Arrays.asList(
			statisticalResultIndexer.getViabilityResults(),
			statisticalResultIndexer.getFertilityResults(),
			statisticalResultIndexer.getReferenceRangePlusResults(),
			statisticalResultIndexer.getUnidimensionalResults(),
			statisticalResultIndexer.getCategoricalResults(),
			statisticalResultIndexer.getEmbryoViabilityResults(),
			statisticalResultIndexer.getEmbryoResults()
		);

		for (Callable<List<StatisticalResultDTO>> r : resultGenerators) {

			System.out.println("Getting ids from " + r.getClass());
			ids.addAll(r.call().stream().map(StatisticalResultDTO::getDocId).collect(Collectors.toList()));

		}

		Set<String> uniques = new HashSet<>();
		Set<String> diff = ids
			.stream()
			.filter(e -> !uniques.add(e))
			.collect(Collectors.toSet());

		assert (diff.isEmpty());
		System.out.println("All generated IDs unique");
	}

}

@@ -217,16 +217,65 @@
 ultDTO;%0A
+import org.springframework.beans.BeansException;%0A
 import o
@@ -394,24 +394,139 @@
 figuration;%0A
+import org.springframework.context.ApplicationContext;%0Aimport org.springframework.context.ApplicationContextAware;%0A
 import org.s
@@ -1191,16 +1191,51 @@
 xerTest 
+implements ApplicationContextAware 
 %7B%0A%0A%09@Aut
@@ -1271,28 +1271,16 @@
 ource;%0A%0A
-%09@Autowired%0A
 %09Statist
@@ -1325,16 +1325,57 @@
 dexer;%0A%0A
+%09ApplicationContext applicationContext;%0A%0A
 %09@PostCo
@@ -1406,16 +1406,18 @@
 uct() %7B%0A
+%0A%0A
 %09%09try %7B%0A
@@ -1417,16 +1417,233 @@
 %09try %7B%0A%0A
+%09%09%09// Use Spring to wire up the dependencies%0A%09%09%09statisticalResultIndexer = StatisticalResultsIndexer.class.newInstance();%0A%09%09%09applicationContext.getAutowireCapableBeanFactory().autowireBean(statisticalResultIndexer);%0A%0A
 %09%09%09stati
@@ -2439,19 +2439,580 @@
 ll);%0A%09%09%7D
-%0A%09%7D
+ catch (InstantiationException e) %7B%0A%09%09%09e.printStackTrace();%0A%09%09%7D catch (IllegalAccessException e) %7B%0A%09%09%09e.printStackTrace();%0A%09%09%7D%0A%09%7D%0A%0A%09@Test%0A%09public void getRrPlusResults() throws Exception %7B%0A%0A%09%09List%3CStatisticalResultDTO%3E results = statisticalResultIndexer.getReferenceRangePlusResults().call();%0A%09%09assert (results.size() %3E 100);%0A%0A%09%09for (StatisticalResultDTO result : results) %7B%0A%0A%09%09%09// Every document that has an MP term must also have at least one top level MP term%0A%09%09%09if (result.getMpTermId() != null) %7B%0A%09%09%09%09assert(result.getTopLevelMpTermId() != null);%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A
 %0A%0A%09@Test
@@ -4211,10 +4211,170 @@
 %22);%0A%09%7D%0A%0A
+%09@Override%0A%09public void setApplicationContext(ApplicationContext applicationContext) throws BeansException %7B%0A%09%09this.applicationContext = applicationContext;%0A%09%7D%0A
 %7D%0A

add test for rr+ results to include top level MP term