package eu.dnetlib.data.utility.cleaner;


import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;

import java.io.StringReader;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnit44Runner;

import com.google.common.collect.Lists;

import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.tools.ServiceLocator;

@RunWith(MockitoJUnit44Runner.class)
public class VocabularyRuleTest {
	private static final String VOCABULARY_NAME = "TEST VOCABULARY";
	private static final List<String> VOCABULARY = Lists.newArrayList(
			"XXXX|-:-|DRIVER|-:-|AAAA",
			"YYYY|-:-|DRIVER|-:-|AAAA",
			"ZZZZ|-:-|DRIVER|-:-|AAAA");
		
	/**
	 * Class Under Test
	 */
	private VocabularyRule rule;
	@Mock
	private ServiceLocator<ISLookUpService> lookupLocator;
	@Mock
	private ISLookUpService lookup;


	@Before
	public void setUp() throws Exception {
		rule = new VocabularyRule();
		rule.setVocabulary(VOCABULARY_NAME);
		rule.setLookupLocator(lookupLocator);

		when(lookupLocator.getService()).thenReturn(lookup);
		when(lookup.quickSearchProfile(anyString())).thenReturn(VOCABULARY);
	}

	@Test
	public void testApplyXpathRule() throws Exception {
		String xpath = "/a/b";
		rule.setXpath(xpath);
		Document doc = execute("<a><b>XXXX</b></a>", null);
		assertEquals("AAAA", doc.valueOf(xpath));
	}
	
	@Test
	public void testApplyXpathRule_2() throws Exception {
		String xpath = "/a/b";
		rule.setXpath(xpath);
		Document doc = execute("<a><b>XXXX</b></a>", "DRIVER");
		assertEquals("AAAA", doc.valueOf(xpath));
	}
	
	@Test
	public void testApplyXpathRule_3() throws Exception {
		String xpath = "/a/b";
		rule.setXpath(xpath);
		Document doc = execute("<a><b>XXXX</b></a>", "INVALID_CONTEXT");
		assertEquals("XXXX", doc.valueOf(xpath));
	}


	@Test
	public void testApplyXpathRule_attr() throws Exception {
		String xpath = "/a/b/@value";
		rule.setXpath(xpath);
		Document doc = execute("<a><b value='XXXX' /></a>", null);
		assertEquals("AAAA", doc.valueOf(xpath));
	}
	

	@Test
	public void testApplyXpathRule_with_spaces() throws Exception {
		String xpath = "/a/b";
		rule.setXpath(xpath);
		Document doc = execute("<a><b>  XXXX  </b></a>", null);
		assertEquals("AAAA", doc.valueOf(xpath));
	}

	@Test
	public void testApplyXpathRule_case() throws Exception {
		String xpath = "/a/b";
		rule.setXpath(xpath);
		Document doc = execute("<a><b>Xxxx</b></a>", null);
		assertEquals("AAAA", doc.valueOf(xpath));
	}
	
	private Document execute(String xml, String context) throws Exception {
		SAXReader reader = new SAXReader();
		Document doc = reader.read(new StringReader(xml));
		System.out.println("BEFORE:\n" + doc.asXML() + "\n");
		rule.applyXpathRule(doc, context);
		System.out.println("AFTER:\n" + doc.asXML() + "\n");
		System.out.println("-----------------------------\n");
		return doc;
	}
}
