/**
 * 
 */
package org.yacos.tests.core;


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

import java.util.Date;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.yacos.core.conferences.Conference;
import org.yacos.core.conferences.IConferenceManager;
import org.yacos.core.system.InvitationToken;
import org.yacos.core.users.IUserManager;
import org.yacos.core.users.User;
import org.yacos.core.users.Role.RoleType;

/**
 * @author christiancorsano
 *
 */
public class InvitationTokenTest {
	private IUserManager userManager;
	private IConferenceManager confManager;
	private Integer testConferenceId;
	
	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		Context context = new InitialContext();
		userManager = (IUserManager) context.lookup("UserManagerBean/remote");
		userManager.addUser("invitationTestChairman", "", "First", "Last", "Yacos", "invitationTestChairman@yacos.com");
		confManager = (IConferenceManager) context.lookup("ConferenceManagerBean/remote");
		confManager.addConferenceCreationToken("invitationTestChairman");
		Conference conf = confManager.addConference(
				"InvitationToken Test conference",
				"invitationTestChairman",
				"A conference to test InvitationToken",
				"None",
				new Date(),
				new Date(),
				new Date(),
				new Date(),
				new Date(),
				0,
				false,
				false,
				false,
				false,
				"Other infos");
		testConferenceId = conf.getId();
	}
	
	@Test
	public void testConferenceReady() throws Exception {
		assertNotNull("Checking presence of conference", confManager.getConference(testConferenceId));
		assertTrue("Checking emptiness of conference token list",
				confManager.getInvitationTokensForConference(testConferenceId).isEmpty());
	}
	
	@Test
	public void testInvitationTokenCreation() throws Exception {
		InvitationToken token = confManager.addInvitationToken("InvitationToken@test.com", RoleType.AUTHOR, testConferenceId);
		List<InvitationToken> tokensForConference = confManager.getInvitationTokensForConference(testConferenceId);
		assertEquals("Checking incrementation of tokens after adding",
				1, tokensForConference.size());
		assertNotNull(token);
		assertEquals("InvitationToken@test.com", token.getEmail());
		assertEquals(RoleType.AUTHOR, token.getRole());
		Conference conf = confManager.getConference(testConferenceId);
		assertEquals(conf.getId(), token.getConference().getId() );
	}
	
	@Test
	public void testInvitationTokenUsedWhenUserCreated() throws Exception {
		confManager.addConferenceCreationToken("invitationTestChairman");
		Conference conf2 = confManager.addConference(
				"InvitationToken Test conference 2",
				"invitationTestChairman",
				"A second conference to test InvitationToken",
				"None",
				new Date(),
				new Date(),
				new Date(),
				new Date(),
				new Date(),
				0,
				false,
				false,
				false,
				false,
				"Other infos");
		
		confManager.addInvitationToken("InvitationToken@test.com", RoleType.AUTHOR, testConferenceId);
		confManager.addInvitationToken("InvitationToken@test.com", RoleType.REFEREE, testConferenceId);
		confManager.addInvitationToken("InvitationToken@test.com", RoleType.PCMEMBER, conf2.getId());
		
		assertEquals(2,confManager.getInvitationTokensForConference(testConferenceId).size());
		assertEquals(1,confManager.getInvitationTokensForConference(conf2.getId()).size());
		assertEquals(3,userManager.getInvitationTokensForEmail("InvitationToken@test.com").size());
		
		User testUser = userManager.addUser("testInvitationToken",
				User.hashPassword("pass"), "ITokenTest", "ITokenTest", "YACOS", "InvitationToken@test.com");
		assertTrue("Checking that all tokens are used when User is created",
				userManager.getInvitationTokensForEmail(testUser.getEmail()).isEmpty());
		assertTrue("Checking the roles for test user",
				userManager.hasRoleForConference(testUser.getLogin(), RoleType.AUTHOR, testConferenceId));
		assertTrue("Checking the roles for test user",
				userManager.hasRoleForConference(testUser.getLogin(), RoleType.REFEREE, testConferenceId));
		assertTrue("Checking the roles for test user",
				userManager.hasRoleForConference(testUser.getLogin(), RoleType.PCMEMBER, conf2.getId()));
		
		assertEquals(0,userManager.getInvitationTokensForEmail("InvitationToken@test.com").size());
		
		// Cleaning up
		userManager.removeUser("testInvitationToken");
		confManager.remove(conf2.getId());
	}

	/**
	 * @throws java.lang.Exception
	 */
	@After
	public void tearDown() throws Exception {
		List<InvitationToken> tokensForConference = confManager.getInvitationTokensForConference(testConferenceId);
		for(InvitationToken token : tokensForConference){
			confManager.removeInvitationToken(token);
		}
		assertTrue("TearDown : checking that no test tokens are left in the database",
				confManager.getInvitationTokensForConference(testConferenceId).isEmpty());
		
		confManager.remove(testConferenceId);
		assertNull("TearDown : checking that the test conference has been removed",
				confManager.getConference(testConferenceId));
		
		userManager.removeUser("invitationTestChairman");
	}

}
