package eu.dnetlib.r2d2.neo4j;

import org.junit.Test;

import com.google.common.collect.Iterables;

import eu.dnetlib.r2d2.neo4j.domain.Neo4jRLEntry;
import eu.dnetlib.r2d2.neo4j.domain.Neo4jRLEntry.Kind;

public class TestExterminators extends
		BaseTestCase {

	private String pid1 = "parent list 1";
	private String pid2 = "parent list 2";
	private String rlid = "list";
	private String chId = "child list 1";
	private String itId = "an item";
	
	@Test public void test() {
		rlDao.newBean(pid1).setName("parent 1");
		rlDao.newBean(pid2).setName("parent 2");
		rlDao.newBean(rlid).setName("to be deleted");
		rlDao.newBean(chId).setName("child list");
		itemDao.newBean(itId).setTitle("add an item too");
		
		// add the rl as contained in the 2 parent lists
		Neo4jRLEntry entry = entryDao.newBean();
		entry.setKind(Kind.READING_LIST);
		entryDao.setInformationObject(entry.getId(), rlid);
		entryDao.addEntryToReadingList(entry.getId(), pid1);
		
		entry = entryDao.newBean();
		entry.setKind(Kind.READING_LIST);
		entryDao.setInformationObject(entry.getId(), rlid);
		entryDao.addEntryToReadingList(entry.getId(), pid2);
		
		// add the child list as contained in rl
		entry = entryDao.newBean();
		entry.setKind(Kind.READING_LIST);
		entryDao.setInformationObject(entry.getId(), chId);
		entryDao.addEntryToReadingList(entry.getId(), rlid);
		
		// add the item to the reading list...
		entry = entryDao.newBean();
		entry.setKind(Kind.ITEM);
		entryDao.setInformationObject(entry.getId(), itId);
		entryDao.addEntryToReadingList(entry.getId(), rlid);
		
		// add the item to another reading list...
		entry = entryDao.newBean();
		entry.setKind(Kind.ITEM);
		entryDao.setInformationObject(entry.getId(), itId);
		entryDao.addEntryToReadingList(entry.getId(), pid1);
		
		// assert that everything worked...
		assertNotNull(entryDao.getEntry(pid1, rlid));
		assertNotNull(entryDao.getEntry(pid2, rlid));
		assertNotNull(entryDao.getEntry(rlid, chId));
		assertNotNull(entryDao.getEntry(rlid, itId));
		
		assertEquals(1, Iterables.size(rlDao.getContainedReadingLists(pid1)));
		assertEquals(1, Iterables.size(rlDao.getContainedReadingLists(pid2)));
		assertEquals(1, Iterables.size(rlDao.getContainedReadingLists(rlid)));
		
		assertEquals(4, Iterables.size(rlDao.getAll()));
		assertEquals(5, Iterables.size(entryDao.getAll()));
		assertEquals(1, Iterables.size(itemDao.getAll()));
		
		// the big time;
		rlDao.deleteBean(rlid);
		
		// assert...
		assertEquals(0, Iterables.size(rlDao.getContainedReadingLists(pid1)));
		assertEquals(0, Iterables.size(rlDao.getContainedReadingLists(pid2)));
		assertEquals(3, Iterables.size(rlDao.getAll()));
		assertEquals(1, Iterables.size(entryDao.getAll()));
		assertEquals(1, Iterables.size(itemDao.getAll()));
		
		// one more delete
		itemDao.deleteBean(itId);
		
		// assert...
		assertEquals(0, Iterables.size(rlDao.getContainedReadingLists(pid1)));
		assertEquals(0, Iterables.size(rlDao.getContainedReadingLists(pid2)));
		assertEquals(3, Iterables.size(rlDao.getAll()));
		assertEquals(0, Iterables.size(entryDao.getAll()));
		assertEquals(0, Iterables.size(itemDao.getAll()));

		// recreate
		rlDao.newBean(rlid).setName("to be deleted");
		itemDao.newBean(itId).setTitle("add an item too");
		
		// add the rl as contained in the 2 parent lists
		entry = entryDao.newBean();
		entry.setKind(Kind.READING_LIST);
		entryDao.setInformationObject(entry.getId(), rlid);
		entryDao.addEntryToReadingList(entry.getId(), pid1);
		
		entry = entryDao.newBean();
		entry.setKind(Kind.READING_LIST);
		entryDao.setInformationObject(entry.getId(), rlid);
		entryDao.addEntryToReadingList(entry.getId(), pid2);
		
		// add the child list as contained in rl
		entry = entryDao.newBean();
		entry.setKind(Kind.READING_LIST);
		entryDao.setInformationObject(entry.getId(), chId);
		entryDao.addEntryToReadingList(entry.getId(), rlid);
		
		// add the item to the reading list...
		entry = entryDao.newBean();
		entry.setKind(Kind.ITEM);
		entryDao.setInformationObject(entry.getId(), itId);
		entryDao.addEntryToReadingList(entry.getId(), rlid);
		
		// add the item to another reading list...
		entry = entryDao.newBean();
		entry.setKind(Kind.ITEM);
		entryDao.setInformationObject(entry.getId(), itId);
		entryDao.addEntryToReadingList(entry.getId(), pid1);
		
		// assert that everything worked...
		assertNotNull(entryDao.getEntry(pid1, rlid));
		assertNotNull(entryDao.getEntry(pid2, rlid));
		assertNotNull(entryDao.getEntry(rlid, chId));
		assertNotNull(entryDao.getEntry(rlid, itId));
		
		assertEquals(1, Iterables.size(rlDao.getContainedReadingLists(pid1)));
		assertEquals(1, Iterables.size(rlDao.getContainedReadingLists(pid2)));
		assertEquals(1, Iterables.size(rlDao.getContainedReadingLists(rlid)));
		
		assertEquals(4, Iterables.size(rlDao.getAll()));
		assertEquals(5, Iterables.size(entryDao.getAll()));
		assertEquals(1, Iterables.size(itemDao.getAll()));
		
		after();
		before();
		
		// the big time, this time in a different tx
		rlDao.deleteBean(rlid);
		
		// assert...
		assertEquals(0, Iterables.size(rlDao.getContainedReadingLists(pid1)));
		assertEquals(0, Iterables.size(rlDao.getContainedReadingLists(pid2)));
		assertEquals(3, Iterables.size(rlDao.getAll()));
		assertEquals(1, Iterables.size(entryDao.getAll()));
		assertEquals(1, Iterables.size(itemDao.getAll()));
		
		// one more delete
		itemDao.deleteBean(itId);
		
		// assert...
		assertEquals(0, Iterables.size(rlDao.getContainedReadingLists(pid1)));
		assertEquals(0, Iterables.size(rlDao.getContainedReadingLists(pid2)));
		assertEquals(3, Iterables.size(rlDao.getAll()));
		assertEquals(0, Iterables.size(entryDao.getAll()));
		assertEquals(0, Iterables.size(itemDao.getAll()));
		
		// we rock man
	}
}