package eu.dnetlib.r2d2.neo4j;

import javax.annotation.Resource;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Transaction;
import org.springframework.test.annotation.AbstractAnnotationAwareTransactionalTests;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import eu.dnetlib.r2d2.neo4j.dao.GroupDao;
import eu.dnetlib.r2d2.neo4j.dao.ProfileDao;
import eu.dnetlib.r2d2.neo4j.dao.ReadingListDao;
import eu.dnetlib.r2d2.neo4j.domain.Neo4jGroup;
import eu.dnetlib.r2d2.neo4j.domain.Neo4jProfile;
import eu.dnetlib.r2d2.neo4j.domain.Neo4jReadingList;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/eu/dnetlib/r2d2/neo4j/applicationContext-neo4j.xml", "/eu/dnetlib/r2d2/neo4j/applicationContext-r2d2-neo4j-test.xml"})
public class TestNeo extends AbstractAnnotationAwareTransactionalTests {
	
	@Resource
	private GraphDatabaseService graphDb = null;
	
	@Resource
	private ProfileDao userManager = null;
	@Resource
	private GroupDao groupManager = null;
	@Resource
	private ReadingListDao rlManager = null;
	
	private static Neo4jProfile profile = null;
	private static String profileId = null;
	private static Neo4jGroup group = null;
	private static String groupId = null;
	
	@BeforeClass
	public static void setup() {
		Logger rootLogger = Logger.getRootLogger();
		if (!rootLogger.getAllAppenders().hasMoreElements()) {
			rootLogger.setLevel(Level.INFO);
			rootLogger.addAppender(new ConsoleAppender(new PatternLayout(PatternLayout.TTCC_CONVERSION_PATTERN)));

			Logger pkgLogger = rootLogger.getLoggerRepository().getLogger(
					"eu.dnetlib");
			pkgLogger.setLevel(Level.DEBUG);
		}
	}
	
	private Transaction tx = null;
	
	@Before
	public void before() {
		tx = graphDb.beginTx();
	}
	
	@After
	public void after() {
		tx.success();
		tx.finish();
	}
	
	@Test
	public void testCreate() {
		profile = userManager.newBean();
		
		profile.setAvatarUrl("http://www.thewiplist.com/photos/G/13796672_ga.jpg");
		profile.setName("Georgios Amanatidis");
		
		profileId = profile.getId();
		
		assertNotNull(profileId);
	}

	@Test
	public void testGetById() throws Exception {
		assertNotNull(profileId);

		profile = userManager.getBean(profileId);
		
		assertNotNull(profile);
		assertEquals(profile.getId(), profileId);
		assertEquals(profile.getName(), "Georgios Amanatidis");
	}
	
	@Test
	public void testEdit() {
		profile = userManager.getBean(profileId);
		assertNotNull(profile);
		assertEquals(profile.getId(), profileId);
		assertEquals(profile.getName(), "Georgios Amanatidis");
		
		profile.setName("Karataidis Gewrgios");
		
		profile = userManager.getBean(profileId);
		
		assertNotNull(profile);
		assertEquals(profile.getName(), "Karataidis Gewrgios");
	}	
	
	@Test
	public void testCreateGroup() {
		group = groupManager.newBean();
		
		group.setName("Coolers");
		group.setDescription("The cool group of cool users");
		group.setAvatarUrl("http://blogs.targetx.com/pbu/Sam/SM131~Mom-Says-I-m-Cool-Posters.jpg");
		
		groupId = group.getId();
		
		assertNotNull(groupId);
	}
	
	@Test
	public void testAddUserToGroup() {
		groupManager.addUserToGroup(groupId, profileId);
		
		Iterable<Neo4jGroup> groups = groupManager.getUserGroups(profileId);
		
		assertNotNull(groups);
		assertTrue(groups.iterator().hasNext());
		assertEquals(groupId, groups.iterator().next().getId());
		assertFalse(groups.iterator().hasNext());
	}
	
	@Test
	public void testRemoveUserFromGroup() {
		groupManager.removeUserFromGroup(groupId, profileId);
		
		Iterable<Neo4jGroup> groups = groupManager.getUserGroups(profileId);
		
		assertNotNull(groups);
		assertFalse(groups.iterator().hasNext());
	}
	
	@Test
	public void testNewReadingList() {
		Neo4jReadingList rl = rlManager.newBean();
		
		rl.setAvatarUrl("234324534");
		rl.setDescription("I rock. You?");
		rl.setName("Rocking rockers");
		
		String rlId = rl.getId();
		
		assertNotNull(rlId);
	}

	public ProfileDao getUserManager() {
		return userManager;
	}

	public void setUserManager(ProfileDao userManager) {
		this.userManager = userManager;
	}

	public GroupDao getGroupManager() {
		return groupManager;
	}

	public void setGroupManager(GroupDao groupManager) {
		this.groupManager = groupManager;
	}

	public ReadingListDao getRlManager() {
		return rlManager;
	}

	public void setRlManager(ReadingListDao rlManager) {
		this.rlManager = rlManager;
	}
	
//	@AfterClass
//	public static void afterClass() {
//		tx = graphDb.beginTx();
//		try {
//			for (Iterator<Neo4jProfile> profs = userManager.search(null); profs.hasNext(); ) {
//				Neo4jProfile prof = profs.next();
//				
//				userManager.deleteBean(prof.getId());
//			}
//			
//			for (Iterator<Neo4jGroup> groups = groupManager.search(null); groups.hasNext(); ) {
//				groupManager.deleteBean(groups.next().getId());
//			}
//		} finally {
//			tx.success();
//			tx.finish();
//		}
//		
//		graphDb.shutdown();
//		index.shutdown();
//		fulltextIndex.shutdown();
//	}
}