package eu.dnetlib.enabling.aas.ismock;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;

import eu.dnetlib.enabling.aas.utils.SpringUtils;
import eu.dnetlib.enabling.is.store.rmi.ISStoreService;

/**
 * @author mhorst
 *
 */
public class MockISStoreTest {

	ApplicationContext ctx;
	ISStoreService storeService;
	
	@Before
	public void setUp() throws Exception {
		ctx = SpringUtils.getSpringContext(SpringUtils.DEFAULT_INTEGRATION_RESOURCE);
		storeService = (ISStoreService) ctx.getBean("MockISStoreService");
	}

	@After
	public void tearDown() throws Exception {
	}
	
	@Test
	public void testService() {
		assertNotNull(storeService);
	}

	@Test
	public void testCreateAndDeleteFileColl() throws Exception {
//		important: collection name must begin with db/
		String fileColl = "db/junitCollection";
		assertTrue(storeService.createFileColl(fileColl));
		List<String> colNames = storeService.getFileColls();
		assertTrue(isNameAmongNames(colNames, fileColl.substring("db/".length())));
		assertTrue(storeService.deleteFileColl(fileColl));
		colNames = storeService.getFileColls();
		assertFalse(isNameAmongNames(colNames, fileColl.substring("db/".length())));
	}

	@Test
	public void testDeleteXml() throws Exception {
		String fileColl = "db/junitCollection";
		String fileName = "junitResource";
		String fileContent = "<someContent><testElement/></someContent>";
		assertTrue(storeService.createFileColl(fileColl));
		assertTrue(storeService.insertXML(fileName, fileColl, fileContent));
		String foundContent = storeService.getXML(fileName, fileColl);
		System.out.println("Found content: "+foundContent);
		assertEquals(fileContent, foundContent);
		assertTrue(storeService.deleteXML(fileName, fileColl));
		String deletedContent = storeService.getXML(fileName, fileColl);
		assertNull(deletedContent);
		assertTrue(storeService.deleteFileColl(fileColl));
	}

	@Test
	public void testGetFileColls() throws Exception {
		List<String> fileColls = storeService.getFileColls();
		assertNotNull(fileColls);
	}


	public void testGetNewFileName() {
//		not implemented
	}

	@Test
	public void testInsertAndgetXML() throws Exception {
		String fileColl = "db/junitCollection";
		String fileName = "junitResource";
		String fileContent = "<someContent><testElement/></someContent>";
		assertTrue(storeService.createFileColl(fileColl));
		assertTrue(storeService.insertXML(fileName, fileColl, fileContent));
		String foundContent = storeService.getXML(fileName, fileColl);
		System.out.println("Found content: "+foundContent);
		assertEquals(fileContent, foundContent);
		assertTrue(storeService.deleteFileColl(fileColl));
	}
	
	@Test
	public void testDeleteArrayXML() throws Exception {
		String fileColl = "db/junitCollection";
		String file1Name = "junitResource1";
		String file2Name = "junitResource2";
		List<String> fileNames = new ArrayList<String>();
		fileNames.add(file1Name);
		fileNames.add(file2Name);
		String fileContent = "<someContent><testElement/></someContent>";
		assertTrue(storeService.createFileColl(fileColl));
		assertTrue(storeService.insertXML(file1Name, fileColl, fileContent));
		assertTrue(storeService.insertXML(file2Name, fileColl, fileContent));
		assertTrue(storeService.deleteArrayXML(fileNames, fileColl));
		List<String> foundNames = storeService.getFileNames(fileColl);
		assertNotNull(foundNames);
		assertEquals(foundNames.size(), 0);
		assertTrue(storeService.deleteFileColl(fileColl));
	}

	@Test
	public void testGetFileNames() throws Exception {
		String fileColl = "db/junitCollection";
		String file1Name = "junitResource1";
		String file2Name = "junitResource2";
		List<String> fileNames = new ArrayList<String>();
		fileNames.add(file1Name);
		fileNames.add(file2Name);
		String fileContent = "<someContent><testElement/></someContent>";
		assertTrue(storeService.createFileColl(fileColl));
		assertTrue(storeService.insertXML(file1Name, fileColl, fileContent));
		assertTrue(storeService.insertXML(file2Name, fileColl, fileContent));
		List<String> foundNames = storeService.getFileNames(fileColl);
		assertNotNull(foundNames);
		assertEquals(foundNames.size(), 2);
		assertTrue(storeService.deleteArrayXML(fileNames, fileColl));
		foundNames = storeService.getFileNames(fileColl);
		assertNotNull(foundNames);
		assertEquals(foundNames.size(), 0);
		assertTrue(storeService.deleteFileColl(fileColl));
	}
	
	@Test
	public void testgetXMLbyQuery() throws Exception {
		String fileColl = "db/junitCollection";
		String file1Name = "junitResource1";
		String file2Name = "junitResource2";
		String[] fileNames = new String[2];
		fileNames[0] = file1Name;
		fileNames[1] = file2Name;
		String fileContent = "<someContent><testElement/></someContent>";
		assertTrue(storeService.createFileColl(fileColl));
		assertTrue(storeService.insertXML(file1Name, fileColl, fileContent));
		assertTrue(storeService.insertXML(file2Name, fileColl, fileContent));
//		String query = "for $el in //someContent[testElement = ''] return $el";
		String query = "for $el in fn:collection(\"junitCollection\")/someContent[testElement = ''] return $el";
		
		String result = storeService.getXMLbyQuery(query);
		assertNotNull(result);
		System.out.println(result);
		assertTrue(storeService.deleteFileColl(fileColl));
	}
	
	public void testSearchXml() {
//		not implemented
	}

	@Test
	public void testUpdateXml() throws Exception {
		String fileColl = "db/junitCollection";
		String fileName = "junitResource";
		String fileContent = "<someContent><testElement/></someContent>";
		String modifiedFileContent = "<someContent><modifiedElement/></someContent>";
		assertTrue(storeService.createFileColl(fileColl));
		assertTrue(storeService.insertXML(fileName, fileColl, fileContent));
		String foundContent = storeService.getXML(fileName, fileColl);
		assertEquals(fileContent, foundContent);
		assertTrue(storeService.updateXML(fileName, fileColl, modifiedFileContent));
		String foundModifiedContent = storeService.getXML(fileName, fileColl);
		assertEquals(modifiedFileContent, foundModifiedContent);
		assertTrue(storeService.deleteFileColl(fileColl));
	}
	
		
	boolean isNameAmongNames(List<String> names, String name) {
		if (names==null || name==null)
			return false;
		for (String currentName : names) {
			if (name.equals(currentName))
				return true;
		}
		return false;
	}

}
