package eu.dnetlib.xml.database.exist;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.io.StringWriter;
import java.util.Arrays;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import org.xmldb.api.base.XMLDBException;

/**
 * test exist dom converter.
 * 
 * @author marko
 *
 */
public class ExistDOMConverterTest {

	/**
	 * logger.
	 */
	static final Log log = LogFactory.getLog(ExistDOMConverterTest.class); // NOPMD by marko on 11/24/08 5:02 PM
	
	/**
	 * test collection.
	 */
	private static final String DB_TEST = "/db/collection";

	/**
	 * check that the document is not truncated.
	 */
	private static final int MIN_LENGTH = 80;
	
	/**
	 * instance under test.
	 */
	private transient ExistDOMConverter converter;

	/**
	 * eXist database instance. 
	 */
	private transient ExistDatabase edb;
	
	/**
	 * true when the eXist trigger is called.
	 */
	private static boolean triggered;
	
	/**
	 * setup common stuff.
	 */
	@Before
	public void setUp() {
		converter = new ExistDOMConverter();
		
		edb = new TemporaryExistDatabase();
		edb.start();
		
		triggered = false;
	}

	/**
	 * check that the ExistDOMConverter works well with plain DOMs.
	 * 
	 * @throws ParserConfigurationException shouldn't happen
	 * @throws SAXException shouldn't happen
	 * @throws IOException shouldn't happen
	 */
	@Test
	public void testAsString() throws ParserConfigurationException, SAXException, IOException {
		final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		final Document doc = builder.parse(getClass().getResourceAsStream("userProfileResourceSchema.xsd"));
		
		assertNotNull("dom", doc);
		
		assertTrue("length", converter.asString(doc).length() > MIN_LENGTH);
	}

	/**
	 * test without comments in preable.
	 * 
	 * @throws XMLDBException shouldn't happen
	 * @throws IOException shouldn't happen
	 */
	@Test
	public void testFromExist() throws XMLDBException, IOException {
		edb.setExistTrigger(DOMConverterTestTrigger.class, DB_TEST, Arrays.asList(new String[] { "store", "update", "delete" }), null);
		
		final StringWriter schema = new StringWriter();
		IOUtils.copy(getClass().getResourceAsStream("userProfileResourceSchemaClean.xsd"), schema);
		edb.create("test", DB_TEST, schema.toString());
		
		final String res = edb.read("test", DB_TEST);
		assertNotNull("check read", res);
		
		assertTrue("check that trigger is executed", triggered);
		
	}
	
	/**
	 * test comments in preable.
	 * 
	 * @throws XMLDBException shouldn't happen
	 * @throws IOException shouldn't happen
	 */
	@Test
	public void testFromExistCommented() throws XMLDBException, IOException {
		edb.setExistTrigger(DOMConverterTestTrigger.class, DB_TEST, Arrays.asList(new String[] { "store", "update", "delete" }), null);
		
		final StringWriter schema = new StringWriter();
		IOUtils.copy(getClass().getResourceAsStream("userProfileResourceSchema.xsd"), schema);
		edb.create("testCommented", DB_TEST, schema.toString());
		
		final String res = edb.read("testCommented", DB_TEST);
		assertNotNull("check read", res);
		
		assertTrue("check that trigger is executed", triggered);	
		//assertFalse("check that trigger is executed", triggered);	
	}

	public static boolean isTriggered() {
		return triggered;
	}

	public static void setTriggered(final boolean triggered) {
		ExistDOMConverterTest.triggered = triggered;
	}

}
