package eu.dnetlib.r2d2.neo4j;

import javax.annotation.Resource;

import org.apache.log4j.BasicConfigurator;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.graphdb.Transaction;
import org.neo4j.kernel.EmbeddedGraphDatabase;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.google.common.collect.Iterables;

import eu.dnetlib.r2d2.neo4j.dao.ItemDao;
import eu.dnetlib.r2d2.neo4j.dao.RLEntryDao;
import eu.dnetlib.r2d2.neo4j.dao.ReadingListDao;
import eu.dnetlib.r2d2.neo4j.domain.Neo4jItem;
import eu.dnetlib.r2d2.neo4j.domain.Neo4jRLEntry;
import eu.dnetlib.r2d2.neo4j.domain.Neo4jReadingList;
import eu.dnetlib.r2d2.neo4j.domain.Neo4jRLEntry.Kind;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/eu/dnetlib/r2d2/neo4j/applicationContext-neo4j.xml", "/eu/dnetlib/r2d2/neo4j/applicationContext-r2d2-neo4j-test.xml"})
public class TestEntries {
	
	@Resource
	private ReadingListDao rlDao = null;

	@Resource
	private RLEntryDao entryDao = null;
	
	@Resource
	private ItemDao itemDao = null;
	
	@Resource
	private EmbeddedGraphDatabase graphdb = null;
	
	@BeforeClass
	public static void setup() {
		BasicConfigurator.configure();
	}
	
	Transaction tx = null;
	@Before
	public void before() {
		tx = graphdb.beginTx();
	}
	
	@After
	public void after() {
		tx.success();
		tx.finish();
	}
	
	@Test
	public void test() {
		// add a couple of extra irrelevant items
		itemDao.newBean().setItemUrl("url1");
		itemDao.newBean().setItemUrl("url2");
		
		// and a few irrelevant rls as well
		rlDao.newBean().setName("I don't care");
		rlDao.newBean().setName("I don't care2");
		rlDao.newBean().setName("I don't care3");
		
		
		Neo4jReadingList rl = rlDao.newBean();
		
		rl.setAvatarUrl("Avatar url");
		rl.setDescription("a coool description");
		rl.setName("Parent reading list");
		
		String rlId = rl.getId();
		
		rl = rlDao.newBean();
		rl.setAvatarUrl("dsf");
		rl.setDescription("fdsf");
		rl.setName("sff");
		Neo4jRLEntry entry = entryDao.newBean();
		entry.setKind(Kind.READING_LIST);
		rlDao.setReadingListOfEntry(rl.getId(), entry.getId());
		entryDao.addEntryToReadingList(entry.getId(), rlId);
		
		
		rl = rlDao.newBean();
		rl.setAvatarUrl("dsf");
		rl.setDescription("fdsf");
		rl.setName("sff");
		entry = entryDao.newBean();
		entry.setKind(Kind.READING_LIST);
		rlDao.setReadingListOfEntry(rl.getId(), entry.getId());
		entryDao.addEntryToReadingList(entry.getId(), rlId);
		
		rl = rlDao.newBean();
		rl.setAvatarUrl("dsf");
		rl.setDescription("fdsf");
		rl.setName("sff");
		entry = entryDao.newBean();
		entry.setKind(Kind.READING_LIST);
		rlDao.setReadingListOfEntry(rl.getId(), entry.getId());
		entryDao.addEntryToReadingList(entry.getId(), rlId);
		
		// test the Neo4jRLEntryDao.getEntry(rlId, IOId) for rls
		Neo4jRLEntry e = entryDao.getEntry(rlId, rl.getId());
		Assert.assertNotNull(entry);
		Assert.assertEquals(entry.getId(), e.getId());
		
		Neo4jItem item = itemDao.newBean();
		entry = entryDao.newBean();
		entry.setKind(Kind.ITEM);
		itemDao.setItemForEntry(item.getId(), entry.getId());
		entryDao.addEntryToReadingList(entry.getId(), rlId);
		
		item = itemDao.newBean();
		entry = entryDao.newBean();
		entry.setKind(Kind.ITEM);
		itemDao.setItemForEntry(item.getId(), entry.getId());
		entryDao.addEntryToReadingList(entry.getId(), rlId);
		
		item = itemDao.newBean();
		entry = entryDao.newBean();
		entry.setKind(Kind.ITEM);
		itemDao.setItemForEntry(item.getId(), entry.getId());
		entryDao.addEntryToReadingList(entry.getId(), rlId);
		
		item = itemDao.newBean();
		entry = entryDao.newBean();
		entry.setKind(Kind.ITEM);
		itemDao.setItemForEntry(item.getId(), entry.getId());
		entryDao.addEntryToReadingList(entry.getId(), rlId);
		
		// test the Neo4jRLEntryDao.getEntry(rlId, IOId) for items
		e = entryDao.getEntry(rlId, item.getId());
		Assert.assertNotNull(entry);
		Assert.assertEquals(entry.getId(), e.getId());
		
		Assert.assertEquals(4, Iterables.size(entryDao.getReadingListEntries(rlId, Kind.ITEM)));
		Assert.assertEquals(3, Iterables.size(entryDao.getReadingListEntries(rlId, Kind.READING_LIST)));
		Assert.assertEquals(4,  Iterables.size(itemDao.getItemsInReadingList(rlId)));
		Assert.assertEquals(3,  Iterables.size(rlDao.getContainedReadingLists(rlId)));
	}
}