package eu.dnetlib.pace.distance;

import static org.junit.Assert.assertTrue;

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

import eu.dnetlib.pace.distance.eval.ScoreResult;
import org.junit.Test;

import com.google.common.collect.Lists;

import eu.dnetlib.pace.AbstractProtoPaceTest;
import eu.dnetlib.pace.config.Config;
import eu.dnetlib.pace.model.MapDocument;

public class DetectorTest extends AbstractProtoPaceTest {

	@Test
	public void testScoreResult() {
		final Config config = getResultProdConf();

		final MapDocument resA = result(config, "A", "Recent results from CDFsd");
		final MapDocument resB = result(config, "B", "Recent results from CDF");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);

		System.out.println(sr.toString());
	}

	@Test
	public void testDistanceResultSimple() {
		final Config config = getResultSimpleConf();

		final MapDocument resA = result(config, "A", "Recent results from CDF");
		final MapDocument resB = result(config, "B", "Recent results from CDF");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue(d == 1.0);
	}

	@Test
	public void testDistanceResultSimpleMissingDates() {
		final Config config = getResultSimpleConf();

		final MapDocument resA = result(config, "A", "Recent results from BES");
		final MapDocument resB = result(config, "A", "Recent results from CES");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue(d > 0.97);
	}

	@Test
	public void testDistanceResultInvalidDate() {
		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "title title title 6BESR", "2013-01-05");
		final MapDocument resB = result(config, "B", "title title title 6BESR", "qwerty");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue(d == 1.0);
	}

	@Test
	public void testDistanceResultMissingOneDate() {
		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "title title title 6BESR", null);
		final MapDocument resB = result(config, "B", "title title title 6CLER", "2012-02");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue((d > 0.9) && (d < 1.0));
	}

	@Test
	public void testDistanceResult() {
		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "title title title BES", "");
		final MapDocument resB = result(config, "B", "title title title CLEO");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue((d > 0.9) && (d < 1.0));
	}

	@Test
	public void testDistanceResultMissingTwoDate() {
		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "title title title 6BESR");
		final MapDocument resB = result(config, "B", "title title title 6CLER");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue((d > 0.9) && (d < 1.0));
	}

	@Test
	public void testDistanceOrganizationIgnoreMissing() {

		final Config config = getOrganizationSimpleConf();

		final MapDocument orgA = organization(config, "A", "CONSIGLIO NAZIONALE DELLE RICERCHE");
		final MapDocument orgB = organization(config, "B", "CONSIGLIO NAZIONALE DELLE RICERCHE", "CNR");

		final ScoreResult sr = new PaceDocumentDistance().between(orgA, orgB, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue(d == 1.0);
	}

	@Test
	public void testDistanceResultCase1() {

		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "Search the Standard Model Higgs boson", "2003");
		final MapDocument resB = result(config, "B", "Search for the Standard Model Higgs Boson", "2003");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue((d > 0.9) && (d < 1.0));
	}

	@Test
	public void testDistanceResultCaseDoiMatch1() {
		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "Search the Standard Model Higgs boson", "2003", "10.1594/PANGAEA.726855");
		final MapDocument resB = result(config, "B", "Search the Standard Model Higgs Boson", "2003", "10.1594/PANGAEA.726855");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue("exact DOIs will produce an exact match", d == 1.0);
	}

	@Test
	public void testDistanceResultCaseDoiMatch2() {
		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "Conference proceedings on X. Appendix", "2003", "10.1594/PANGAEA.726855");
		final MapDocument resB = result(config, "B", "Search the Standard Model Higgs Boson", "2005", "10.1594/PANGAEA.726855");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue("exact DOIs will produce an exact match, regardless of different titles or publication years", d == 1.0);
	}

	@Test
	public void testDistanceResultCaseDoiMatch3() {
		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "Conference proceedings on X. Appendix", "2003", "10.1016/j.jmb.2010.12.024");
		final MapDocument resB = result(config, "B", "Conference proceedings on X. Appendix", "2003");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue("a missing DOI will casue the comparsion to continue with the following conditions", d == 1.0);
	}

	@Test
	public void testDistanceResultCaseDoiMatch4() {
		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "Conference proceedings on X. Appendix", "2003", "10.1016/j.jmb.2010.12.024");
		final MapDocument resB = result(config, "B", "Conference proceedings on X. Appendix", "2005");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue("a missing DOI, comparsion continues with the following conditions, different publication years will drop the score to 0", d == 0.0);
	}

	@Test
	public void testDistanceResultCaseDoiMatch5() {

		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "Search for the Standard Model Higgs Boson", "2003", "10.1016/j.jmb.2010.12.020");
		final MapDocument resB = result(config, "B", "Search the Standard Model Higgs Boson", "2003");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue("a missing DOI, comparsion continues with the following conditions", (d > 0.9) && (d < 1.0));
	}

	@Test
	public void testDistanceResultCaseDoiMatch6() {
		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "Conference proceedings on X. Appendix", "2003", "10.1016/j.jmb.2010.12.024");
		final MapDocument resB = result(config, "B", "Conference proceedings on X. Appendix", "2003", "anotherDifferentDOI");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue("different DOIs will drop the score to 0, regardless of the other fields", d == 0.0);
	}

	@Test
	public void testDistanceResultCaseDoiMatch7() {
		final Config config = getResultConf();

		final MapDocument resA = result(config, "A", "Adrenal Insufficiency asd asd", "1951", Lists.newArrayList("PMC2037944", "axdsds"));
		final MapDocument resB = result(config, "B", "Adrenal Insufficiency", "1951", "PMC2037944");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue("different DOIs will drop the score to 0, regardless of the other fields", d > 0.9 & d < 1);
	}

	// http://dx.doi.org/10.1594/PANGAEA.726855 doi:10.1594/PANGAEA.726855

	@Test
	public void testDistanceResultCaseAuthor1() {

		final Config config = getResultAuthorsConf();

		final List<String> authorsA = Lists.newArrayList("a", "b", "c", "d");
		final List<String> authorsB = Lists.newArrayList("a", "b", "c");
		final List<String> pid = Lists.newArrayList();

		final MapDocument resA = result(config, "A", "Search the Standard Model Higgs Boson", "2003", pid, authorsA);
		final MapDocument resB = result(config, "B", "Search the Standard Model Higgs Boson", "2003", pid, authorsB);

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue(d == 0.0);
	}

	@Test
	public void testDistanceResultCaseAuthor2() {

		final Config config = getResultAuthorsConf();

		final List<String> authorsA = Lists.newArrayList("a", "b", "c");
		final List<String> authorsB = Lists.newArrayList("a", "b", "c");
		final List<String> pid = Lists.newArrayList();

		final MapDocument resA = result(config, "A", "Search the Standard Model Higgs Boson", "2003", pid, authorsA);
		final MapDocument resB = result(config, "B", "Search the Standard Model Higgs Boson", "2003", pid, authorsB);

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue(d == 1.0);
	}

	@Test
	public void testDistanceResultCaseAuthor3() {

		final Config config = getResultAuthorsConf();

		final List<String> authorsA = Lists.newArrayList("Bardi, A.", "Manghi, P.", "Artini, M.");
		final List<String> authorsB = Lists.newArrayList("Bardi Alessia", "Manghi Paolo", "Artini Michele");
		final List<String> pid = Lists.newArrayList();

		final MapDocument resA = result(config, "A", "Search the Standard Model Higgs Boson", "2003", pid, authorsA);
		final MapDocument resB = result(config, "B", "Search the Standard Model Higgs Boson", "2003", pid, authorsB);

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue((d > 0.9) && (d < 1.0));
	}

	@Test
	public void testDistanceResultCaseAuthor4() {

		final Config config = getResultAuthorsConf();

		final List<String> authorsA = Lists.newArrayList("Bardi, Alessia", "Manghi, Paolo", "Artini, Michele", "a");
		final List<String> authorsB = Lists.newArrayList("Bardi Alessia", "Manghi Paolo", "Artini Michele");
		final List<String> pid = Lists.newArrayList();

		final MapDocument resA = result(config, "A", "Search the Standard Model Higgs Boson", "2003", pid, authorsA);
		final MapDocument resB = result(config, "B", "Search the Standard Model Higgs Boson", "2003", pid, authorsB);

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		// assertTrue(d.getScore() == 0.0);
	}

	@Test
	public void testDistanceResultFullConf() {

		final Config config = getResultFullConf();

		final List<String> authorsA = Lists.newArrayList("Nagarajan Pranesh", "Guy Vautier", "Punyanganie de Silva");
		final List<String> authorsB = Lists.newArrayList("Pranesh Nagarajan", "Vautier Guy", "de Silva Punyanganie");

		final MapDocument resA =
				result(config, "A", "Presentations of perforated colonic pathology in patients with polymyalgia rheumatica: two case reports", "2010",
						"10.1186/1752-1947-4-299", authorsA);

		final MapDocument resB =
				result(config, "B", "Presentations of perforated colonic pathology in patients with polymyalgia rheumatica: two case reports", "2010",
						"10.1186/1752-1947-4-299", authorsB);

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		// assertTrue(d.getScore() == 0.0);
	}

	@Test
	public void testDistanceProdConf1() {

		final Config config = getResultProdConf();

		final MapDocument resA =
				result(config,
						"A",
						" Analysis of Transfer Embryo-Derived de-duplication");
		final MapDocument resB =
				result(config,
						"B",
						" Analysis of Transfer Embryo Derived deduplication");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		// assertTrue(d.getScore() == 0.0);
	}

	@Test
	public void testDistanceProdConf2() {

		final Config config = getResultProdConf();

		final MapDocument resA =
				result(config,
						"A",
						"qwerty aaabbbbbbbb bbb ccc ddddd");
		final MapDocument resB =
				result(config,
						"B",
						"qwert aaabbbbbbbb bbb ccc ddddd");

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		// assertTrue(d.getScore() == 0.0);
	}

	@Test
	public void testDistanceProdConf3() {

		final Config config = getResultProdConf();

		final List<String> authorsA = Lists.newArrayList("Bardi, Alessia", "Manghi, Paolo", "Artini, Michele", "a");
		final List<String> authorsB = Lists.newArrayList("Bardi Alessia", "Manghi Paolo", "Artini Michele");
		final List<String> pid = Lists.newArrayList();

		final MapDocument resA =
				result(config,
						"A",
						"qwerty aaabbbbbbbb bbb ccc ddddd", "2003", pid, authorsA);
		final MapDocument resB =
				result(config,
						"B",
						"qwert aaabbbbbbbb bbb ccc ddddd", "2003", pid, authorsB);

		final ScoreResult sr = new PaceDocumentDistance().between(resA, resB, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		assertTrue(d == 0.0);
	}

	@Test
	public void testDistancePersonConf1() {

		final Config config = getPersonConf();

		final MapDocument p1 = person(config, "p1_id", getPersonGT("/eu/dnetlib/pace/model/gt.author.manghi1.fo.json"));
		final MapDocument p2 = person(config, "p2_id", getPersonGT("/eu/dnetlib/pace/model/gt.author.manghi2.fo.json"));

		final ScoreResult sr = new PaceDocumentDistance().between(p1, p2, config);
		final double d = sr.getScore();
		System.out.println(String.format(" d ---> %s", d));

		// assertTrue(d.getScore() == 0.0);
	}

}
