package eu.dnetlib.enabling.tools;

import static org.junit.Assert.*; // NOPMD
import static org.mockito.Mockito.*; // NOPMD

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;

import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;

/**
 * Test DOM opaque resource.
 * 
 * @author marko
 * 
 */
public class DOMOpaqueResourceTest {

	/**
	 * instance under test.
	 */
	private transient DOMOpaqueResource resource;

	/**
	 * xml source, read from test-profile.xml.
	 */
	private transient String xmlSource;

	/**
	 * common preparation.
	 * 
	 * @throws ParserConfigurationException
	 *             shouldn't happen
	 * @throws IOException
	 *             shouldn't happen
	 * @throws SAXException
	 *             shouldn't happen
	 * @throws XPathExpressionException
	 *             shouldn't happen
	 */
	@Before
	public void setUp() throws SAXException, IOException, ParserConfigurationException, XPathExpressionException {
		final StringWriter writer = new StringWriter();
		IOUtils.copy(getClass().getResourceAsStream("test-profile.xml"), writer);
		xmlSource = writer.getBuffer().toString();
		final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(xmlSource)));
		resource = new DOMOpaqueResource(document);
	}

	/**
	 * test dom.
	 */
	@Test
	public void testAsDom() {
		assertEquals("check that dom is not recreated", resource.getDom(), resource.asDom());
	}

	/**
	 * serialization check.
	 * 
	 * TODO: use xmlunit
	 */
	@Test
	public void testAsString() {
		assertEquals("check xml serialization", xmlSource, resource.asString());
	}

	/**
	 * test with exception in transformer.
	 * @throws TransformerException expected
	 */
	@Test
	public void testAsStringException() throws TransformerException {
		final Transformer transformer = mock(Transformer.class);
		doThrow(new TransformerException("dummy")).when(transformer).transform((Source) anyObject(), (Result) anyObject());

		resource.setTransformer(transformer);
		assertNull("checks that upon exception we get a null string", resource.asString());
	}

	/**
	 * check resource id extraction.
	 */
	@Test
	public void testGetResourceId() {
		assertEquals("check resource id",
				"111-6b4ea417-d940-4dda-a194-3096f685789b_UmVwb3NpdG9yeVNlcnZpY2VSZXNvdXJjZXMvUmVwb3NpdG9yeVNlcnZpY2VSZXNvdXJjZVR5cGU=", resource
						.getResourceId());
	}

	/**
	 * check resource type extraction.
	 */
	@Test
	public void testGetResourceType() {
		assertEquals("check resource type", "RepositoryServiceResourceType", resource.getResourceType());
	}

	/**
	 * check resource kind extraction.
	 */
	@Test
	public void testGetResourceKind() {
		assertEquals("check resource kind", "RepositoryServiceResources", resource.getResourceKind());
	}

}
