package eu.dnetlib.api.client;

import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.apache.http.client.utils.URIBuilder;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.DocumentSource;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXException;

public class SygmaApiClientTest extends OpenaireApiClientTest {

	private SchemaFactory schemaFactory;
	private Schema sygmaSchema;
	private Validator validator;

	@Before
	public void setup() throws URISyntaxException, SAXException {
		schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
		URL schemaUrl = this.getClass().getResource("/eu/dnetlib/oaf_sygma_v2.1.xsd");
		File schemaFile = new File(schemaUrl.toURI());
		sygmaSchema = schemaFactory.newSchema(schemaFile);
		validator = sygmaSchema.newValidator();
	}

	private void validate(final Source response) throws SAXException, IOException {
		validator.validate(response);
	}

	private void validate(final Document doc) throws SAXException, IOException {
		Source source = new DocumentSource(doc);
		validate(source);
	}

	@Test
	public void testPublicationsSygma() throws URISyntaxException, SAXException, IOException {
		URIBuilder builder = new URIBuilder(requestBaseURL);
		builder.setPath(publicationsPath);
		URI testURI = builder.build();
		System.out.println(testURI);
		// String results = apiClient.doRequest(EntityType.publication, ApiModel.sygma, testURI);
		// System.out.println(results.toString());
		validate(getApiClient().doRequestAsSource(EntityType.publication, ApiModel.sygma, testURI));
	}

	@Test
	public void testPublicationsSygmaLongPage() throws URISyntaxException, SAXException, IOException, DocumentException {
		int pageSizeMax = 1000;
		URIBuilder builder = new URIBuilder(requestBaseURL).setPath(publicationsPath).addParameter("size", "" + pageSizeMax);
		URI testURI = builder.build();
		System.out.println(testURI);
		validate(getApiClient().doRequestAsSource(EntityType.publication, ApiModel.sygma, testURI));
	}

	/*
	 * <code>237920</code> <acronym>UNILHC</acronym> <startdate>2009-10-01</startdate> <enddate>2013-09-30</enddate>
	 * <callidentifier>FP7-PEOPLE-ITN-2008</callidentifier><objIdentifier>corda_______::c2be0603909ad6004c5ab217e130b532</objIdentifier>
	 * UNILHC is currently the most referenced project with about 1.000 publications
	 */
	@Test
	public void testPublicationsByProject() throws URISyntaxException, SAXException, IOException, DocumentException {
		int pageSizeMax = 10000;
		String grantID = "237920";
		String acronym = "UNILHC";

		URIBuilder builder = new URIBuilder(requestBaseURL).setPath(publicationsPath).addParameter("projectID", grantID).addParameter("size", pageSizeMax + "");
		URI testURI = builder.build();
		System.out.println(testURI);
		String results = getApiClient().doRequest(EntityType.publication, ApiModel.sygma, testURI);
		Document doc = DocumentHelper.parseText(results);
		int pageSize = Integer.parseInt(doc.selectSingleNode("//*[local-name()='header']/*[local-name()='size']").getText());
		int total = Integer.parseInt(doc.selectSingleNode("//*[local-name()='header']/*[local-name()='total']").getText());
		assertTrue(total <= pageSizeMax);
		assertTrue(total <= pageSize);
		System.out.println("Number of pubs for project " + grantID + ", acro " + acronym + ": " + total);
		validate(doc);
	}

	@Test
	public void testPublicationsByProjectAndSort() throws URISyntaxException, SAXException, IOException, DocumentException {
		int pageSizeMax = 10000;
		String grantID = "237920";

		URIBuilder builder = new URIBuilder(requestBaseURL).setPath(publicationsPath).addParameter("projectID", grantID).addParameter("size", pageSizeMax + "")
				.addParameter("sortBy", "resultdateofacceptance,ascending");
		URI testURI = builder.build();
		System.out.println(testURI);
		String results = getApiClient().doRequest(EntityType.publication, ApiModel.sygma, testURI);
		Document doc = DocumentHelper.parseText(results);
		validate(doc);
	}

	@Test
	public void testPublicationsByProjectAndSortAndFromDate() throws URISyntaxException, SAXException, IOException, DocumentException {
		int pageSizeMax = 10000;
		String grantID = "237920";

		URIBuilder builder = new URIBuilder(requestBaseURL).setPath(publicationsPath).addParameter("projectID", grantID).addParameter("size", pageSizeMax + "")
				.addParameter("sortBy", "resultdateofacceptance,ascending").addParameter("fromDateAccepted", "2010-01-01");
		URI testURI = builder.build();
		System.out.println(testURI);
		String results = getApiClient().doRequest(EntityType.publication, ApiModel.sygma, testURI);
		Document doc = DocumentHelper.parseText(results);
		validate(doc);
	}

	@Test
	public void testDatasetsSygma() throws URISyntaxException, SAXException, IOException {
		URIBuilder builder = new URIBuilder(requestBaseURL);
		builder.setPath(datasetsPath);
		URI testURI = builder.build();
		System.out.println(testURI);
		// String results = apiClient.doRequest(EntityType.dataset, ApiModel.sygma, testURI);
		// System.out.println(results);
		validate(getApiClient().doRequestAsSource(EntityType.dataset, ApiModel.sygma, testURI));
	}

	@Test
	public void testDatasetsSygmaPage2() throws URISyntaxException, SAXException, IOException {
		URIBuilder builder = new URIBuilder(requestBaseURL);
		builder.setPath(datasetsPath);
		builder.setParameter("page", "2");
		URI testURI = builder.build();
		System.out.println(testURI);
		// String results = apiClient.doRequest(EntityType.dataset, ApiModel.sygma, testURI);
		// System.out.println(results);
		validate(getApiClient().doRequestAsSource(EntityType.dataset, ApiModel.sygma, testURI));
	}

	@Test
	public void testDatasetsSygmaLongPage() throws URISyntaxException, SAXException, IOException, DocumentException {
		int pageSizeMax = 1000;
		URIBuilder builder = new URIBuilder(requestBaseURL).setPath(datasetsPath).addParameter("size", "" + pageSizeMax);
		URI testURI = builder.build();
		System.out.println(testURI);
		validate(getApiClient().doRequestAsSource(EntityType.dataset, ApiModel.sygma, testURI));
	}

	/*
	 * <objIdentifier>corda_______::477201c91d06478cb2828771acea1655</objIdentifier> <code>211089</code> <acronym>OLFPERCEPT</acronym>
	 * <callidentifier>ERC-2007-StG</callidentifier> OLFPERCEPT is currently the most referenced project by datasets with 4 dataset :(
	 */
	@Test
	public void testDatasetsByProject() throws URISyntaxException, SAXException, IOException, DocumentException {
		int pageSizeMax = 10000;
		String grantID = "211089";
		String acronym = "OLFPERCEPT";

		URIBuilder builder = new URIBuilder(requestBaseURL).setPath(datasetsPath).addParameter("projectID", grantID).addParameter("size", pageSizeMax + "");
		URI testURI = builder.build();
		System.out.println(testURI);
		String results = getApiClient().doRequest(EntityType.dataset, ApiModel.sygma, testURI);
		Document doc = DocumentHelper.parseText(results);
		int pageSize = Integer.parseInt(doc.selectSingleNode("//*[local-name()='header']/*[local-name()='size']").getText());
		int total = Integer.parseInt(doc.selectSingleNode("//*[local-name()='header']/*[local-name()='total']").getText());
		assertTrue(total <= pageSizeMax);
		assertTrue(total <= pageSize);
		System.out.println("Number of dataset for project " + grantID + ", acro " + acronym + ": " + total);
		validate(doc);
	}

	@Test
	public void testDatasetsByProjectAndSort() throws URISyntaxException, SAXException, IOException, DocumentException {
		int pageSizeMax = 10000;
		String grantID = "211089";

		URIBuilder builder = new URIBuilder(requestBaseURL).setPath(datasetsPath).addParameter("projectID", grantID).addParameter("size", pageSizeMax + "")
				.addParameter("sortBy", "resultdateofacceptance,ascending");
		URI testURI = builder.build();
		System.out.println(testURI);
		String results = getApiClient().doRequest(EntityType.publication, ApiModel.sygma, testURI);
		Document doc = DocumentHelper.parseText(results);
		validate(doc);
	}

	@Test
	public void testDatasetsByProjectAndSortByCollectiondateAndFromDate() throws URISyntaxException, SAXException, IOException, DocumentException {
		int pageSizeMax = 10000;
		String grantID = "237920";

		URIBuilder builder = new URIBuilder(requestBaseURL).setPath(publicationsPath).addParameter("projectID", grantID).addParameter("size", pageSizeMax + "")
				.addParameter("sortBy", "dateofcollection,ascending").addParameter("fromDateAccepted", "2010-01-01");
		URI testURI = builder.build();
		System.out.println(testURI);
		String results = getApiClient().doRequest(EntityType.publication, ApiModel.sygma, testURI);
		Document doc = DocumentHelper.parseText(results);
		validate(doc);
	}

}
