package eu.dnetlib.resolver;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

import eu.dnetlib.data.transform.OntologyLoader;
import eu.dnetlib.dli.DLIUtils;
import eu.dnetlib.dli.resolver.NCBINParser;
import eu.dnetlib.dli.resolver.NCBINResolver;
import eu.dnetlib.dli.resolver.OpenAireParser;
import eu.dnetlib.dli.resolver.model.CompletionStatus;
import eu.dnetlib.dli.resolver.model.ObjectProvenance;
import eu.dnetlib.dli.resolver.model.ObjectProvisionMode;
import eu.dnetlib.dli.resolver.model.ResolvedObject;
import eu.dnetlib.dli.resolver.model.serializer.ResolverSerializer;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
import eu.dnetlib.resolver.parser.DMFResolverParser;
import eu.dnetlib.resolver.parser.PMFResolverParser;
import eu.dnetlib.resolver.parser.ScholixResolverParser;
import eu.dnetlib.resolver.store.ConfigurationResolverStoreTestConfig;
import eu.dnetlib.rmi.enabling.ISLookUpException;
import eu.dnetlib.rmi.enabling.ISLookUpService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.mockito.Mockito.when;

/**
 * Created by sandro on 9/12/16.
 */


//@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration(classes = { ConfigurationTestConfig.class, ConfigurationResolverStoreTestConfig.class })

@Ignore
public class DLIParserTest {

	private static final Log log = LogFactory.getLog(DLIParserTest.class);

	@Mock
	private DLIUtils dliUtilsInstance;


	@Mock
	private UniqueServiceLocator uniqueServiceLocator;

	@Mock
	private ISLookUpService isLookUpServiceMock;

	@Autowired
	private ResolverSerializer serializer;


	@Before
	public void initialize() throws ISLookUpException, IOException {

		final String query = "for $x in collection('/db/DRIVER/RepositoryServiceResources/RepositoryServiceResourceType') "
				+ "return concat($x//FIELD[./key='NamespacePrefix']/value/text(),'@--@',$x//FIELD[./key='DataSourceId']/value/text(),'@--@',$x//ENGLISH_NAME )";
		dliUtilsInstance = Mockito.mock(DLIUtils.class);

		uniqueServiceLocator = Mockito.mock(UniqueServiceLocator.class);
		isLookUpServiceMock = Mockito.mock(ISLookUpService.class);
		dliUtilsInstance.setServiceLocator(uniqueServiceLocator);
		DLIUtils.setInstance(dliUtilsInstance);
		when(dliUtilsInstance.getServiceLocator()).thenReturn(uniqueServiceLocator);
		when(uniqueServiceLocator.getService(ISLookUpService.class)).thenReturn(isLookUpServiceMock);
		List<String> resutlDS = Arrays.asList(
				"r3d100010255@--@dli_________::r3d100010255@--@icpsr",
				"datacite____@--@dli_________::datacite____@--@Datasets in Datacite",
                "r3d100010134@--@dli_________::r3d100010134@--@pangaea",
                "r3d100010527@--@dli_________::r3d100010527@--@European Nucleotide Archive"

		);
		when(isLookUpServiceMock.quickSearchProfile(query)).thenReturn(resutlDS);
		DLIUtils.ontologies = OntologyLoader.loadOntologiesFromCp();


	}

	@Test
	public void testDMFParser() throws IOException {
		final InputStream resourceAsStream = getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputRecordDMF.xml");
		String str = IOUtils.toString(resourceAsStream);
		DMFResolverParser parser = new DMFResolverParser();
		ResolvedObject object = parser.parseObject(str);
		Assert.assertNotNull(object);
		Assert.assertNotNull(object.getTitles());
		Assert.assertNotNull(object.getType());
		object.setTitles(Arrays.asList("TITOLO 1", "TITOLO 2"));
		Assert.assertEquals(CompletionStatus.complete.toString(), object.getCompletionStatus());
		ResolvedObject nullObject = parser.parseObject(IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputRecordScholix.xml")));
		Assert.assertNull(nullObject);
		nullObject = parser.parseObject(IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputPMFRecord.xml")));
		Assert.assertNull(nullObject);

	}


	@Test
	public void testResolvedDate() throws IOException {
		final InputStream resourceAsStream = getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputPMF.xml");
		String str = IOUtils.toString(resourceAsStream);

		PMFResolverParser parser = new PMFResolverParser();
		ResolvedObject object = parser.parseObject(str);
		Assert.assertNotNull(object.getResolvedDate());
	}


	@Test
	public void testDataciteParser() throws Exception {

		final InputStream resourceAsStream = getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputRecordOpenaire.xml");
		String str = IOUtils.toString(resourceAsStream);
		DMFResolverParser parser = new DMFResolverParser();
		ResolvedObject object = parser.parseObject(str);
		System.out.println(object.getType());
		object.getRelations().forEach(it -> System.out.println(it.getTargetPID()));
		Assert.assertTrue(object.getCompletionStatus().equals("complete"));
		System.out.println("object = " + object);

		final String replacingXML = serializer.serializeReplacingXML(str, object);

		log.debug(replacingXML);



	}

	@Test
	public void testScholixParser() throws IOException {
		final InputStream resourceAsStream = getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputRecordScholix.xml");

		String str = IOUtils.toString(resourceAsStream);
		ScholixResolverParser parser = new ScholixResolverParser();
		ResolvedObject object = parser.parseObject(str);

		log.debug("object = " + object);

		Assert.assertNotNull(object);
		log.debug("object.getCompletionStatus() = " + object.getCompletionStatus());

		Assert.assertTrue(object.getCompletionStatus().equals(CompletionStatus.incomplete.toString()));

		Assert.assertNotNull(object.getRelations());

		Assert.assertTrue(object.getRelations().size() == 1);

		ResolvedObject nullObject = parser.parseObject(IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputRecordDMF.xml")));
		Assert.assertNull(nullObject);
		nullObject = parser.parseObject(IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputPMFRecord.xml")));
		Assert.assertNull(nullObject);

	}

	@Test
	public void testScholixCompleteParser() throws IOException {
		final InputStream resourceAsStream = getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputRecordScholix.xml");

		String str = IOUtils.toString(resourceAsStream);
		ScholixResolverParser parser = new ScholixResolverParser();
		ResolvedObject object = parser.parseObject(str);

		log.debug("object = " + object);

		Assert.assertNotNull(object);
		log.debug("object.getCompletionStatus() = " + object.getCompletionStatus());

//		Assert.assertTrue(object.getCompletionStatus().equals(CompletionStatus.complete.toString()));
//
//		Assert.assertNotNull(object.getDate());
//		Assert.assertNotNull(object.getTitles());
//		Assert.assertTrue(object.getTitles().size() == 1);
//
//		Assert.assertNotNull(object.getDatasourceProvenance());
//		Assert.assertTrue(object.getDatasourceProvenance().size() == 1);
//		Assert.assertNotNull(object.getDatasourceProvenance().get(0).getPublisher());
//		Assert.assertNotNull(object.getDatasourceProvenance().get(0).getPublisherId());
//
//
//		Assert.assertNotNull(object.getRelations());
//
//		Assert.assertTrue(object.getRelations().size() == 1);
//
//		Assert.assertNotNull(object.getRelations().get(0).getTargetPID().getId());
//		Assert.assertNotNull(object.getRelations().get(0).getTargetPID().getType());
//
//
//		ResolvedObject nullObject = parser.parseObject(IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputRecordDMF.xml")));
//		Assert.assertNull(nullObject);
//		nullObject = parser.parseObject(IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputPMFRecord.xml")));
//		Assert.assertNull(nullObject);

	}


	@Test
	public void testPMFParser() throws Exception {
		final InputStream resource = getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputPMF.xml");
		String xml = IOUtils.toString(resource);

		PMFResolverParser parser = new PMFResolverParser();
		final ResolvedObject resolvedObject = parser.parseObject(xml);
		Assert.assertNotNull(resolvedObject);
		log.debug("resolvedObject = " + resolvedObject);

		Assert.assertNotNull(resolvedObject.getRelations());
		resolvedObject.getRelations().forEach(it -> Assert.assertNotNull(it));

		ResolvedObject nullObject = parser.parseObject(IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputRecordScholix.xml")));
		Assert.assertNull(nullObject);
		nullObject = parser.parseObject(IOUtils.toString(getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputRecordDMF.xml")));
		Assert.assertNull(nullObject);
	}

	@Test
	public void testOpenAIREParser() throws Exception {

		final InputStream resource = getClass().getResourceAsStream("/eu/dnetlib/dli/parser/InputRecordOpenaire.xml");

		final String record = IOUtils.toString(resource);

		final OpenAireParser parser = new OpenAireParser();
		final ResolvedObject object = parser.parseObject(record);
		object.setPid("od_______908::ff0270cae25acd9367ef26a53ee5e4a3");
		object.setPidType("openaire");

		ObjectProvenance provenance = new ObjectProvenance();
		provenance.setCompletionStatus(CompletionStatus.complete.toString());
		provenance.setDatasourceId("dli::r3d100010778");
		provenance.setDatasource("NCBI Nucleotide");
		provenance.setProvisionMode(ObjectProvisionMode.resolved.toString());
		object.setDatasourceProvenance(Arrays.asList(provenance));

		log.debug(object);

	}

	@Test
	public void testProteinParser() throws IOException {
		final NCBINResolver resolver = new NCBINResolver();
		resolver.setNCBINParser(new NCBINParser());
		final ResolvedObject p02768 = resolver.resolve("U36380", "protein");

		log.debug(p02768.getDescription());
		Assert.assertNotNull(p02768);
		Assert.assertNotNull(p02768.getDescription());

		log.debug("p02768 = " + p02768);

	}









}
