package org.yacos.tests.core;

import static org.junit.Assert.*;
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.exceptions.PKAlreadyUsedException;
import org.yacos.core.exceptions.UserEMailAlreadyExistsException;
import org.yacos.core.users.IUserManager;
import org.yacos.core.users.Role;
import org.yacos.core.users.User;
import org.yacos.core.users.Role.RoleType;

public class UserTest {
	private IUserManager manager;
	private IConferenceManager confManager;
	private Conference conference;
	
	User user;
	@Before
	public void setUp() throws Exception {
		Context context = new InitialContext();
		manager = (IUserManager) context.lookup("UserManagerBean/remote");
		confManager = (IConferenceManager) context.lookup("ConferenceManagerBean/remote");
		
		user = manager.addUser("testUser1",User.hashPassword("mp"),"bruno","dupont","ipint","e@e.fr");
		
		
		Date dateArticles = new Date();
		conference = confManager.addConference("A Conference",
						"Test symposium 2008",
						"Some infos",
						dateArticles,
						dateArticles,
						dateArticles,
						dateArticles,
						dateArticles);
		
	}
	
	@Test
	public void testManagerPresence(){
		assertNotNull(manager);
	}
	
	@Test
	public void testUserWritingReading() throws Exception{
		user = manager.addUser("testUser",
				User.hashPassword("aPassword"),
				"Bob", "Smith",
				"MIT", "bob.smith@yacos.mit.org");
		assertNotNull(user);
		
		user = manager.getUser("testUser");
		
		assertNotNull(user);
		assertEquals("testUser", user.getLogin());
		assertEquals("Smith", user.getLastName());
		assertEquals("Bob", user.getFirstName());
		assertEquals("MIT", user.getOrganization());
		assertEquals("bob.smith@yacos.mit.org", user.getEmail());
		assertEquals(User.hashPassword("aPassword"), user.getPassword());
		
		try{
			manager.addUser("testUser", "", "", "", "", "");
			fail("Duplicate user created");
		} catch(PKAlreadyUsedException e){
		}
		
		manager.removeUser(user.getLogin());
	}
	
	@Test
	public void testUpdateUser(){
		//on change l'email
		user.setEmail("a@a.fr");
		manager.UpdateUser(user);
		user = manager.getUser("testUser1");
		assertEquals("a@a.fr", user.getEmail());
	}
	
	@Test
	public void testRemoveUser(){
		manager.removeUser(user.getLogin());
		user = manager.getUser("testUser1");
		assertNull(user);
	}
	
	@Test
	public void testAddRole(){
		List<Role> roles = manager.getRolesForUser(user.getLogin());
		int count = roles.size();
		manager.addRoleForConference(user.getLogin(),RoleType.AUTHOR,conference.getId());
		roles = manager.getRolesForUser(user.getLogin());
		assertTrue(count+1 == roles.size());
	}
	
	@Test
	public void testGetConferences(){
		//List<Conference> list = user.getConferences();
		//assertNotNull(list);
		
	}
	
	@Test
	public void testUserExists(){
		assertTrue(manager.exists("testUser1"));
	}
	
	@Test(expected=PKAlreadyUsedException.class)
	public void testUserExistsException() throws Exception {
		manager.addUser("testUser1","pw","First","Last","Orga","someEmailNotUsedYet@somewhere.com");
	}
	
	@Test(expected=UserEMailAlreadyExistsException.class)
	public void testUserEmailExistsException() throws Exception {
		manager.addUser("anotherUserLoginForTestUser1",User.hashPassword("mp"),"bruno","dupont","ipint","e@e.fr");
	}
	
	@After
	public void cleanup(){
		user = manager.getUser("testUser1");
		if(user != null){
			for(Role role : manager.getRolesForUser(user.getLogin())){
				manager.removeRole(user.getLogin(), role.getType(), role.getConference().getId());
			}
			manager.removeUser(user.getLogin());
		}
		
		if(conference != null){
			confManager.remove(conference.getId());
		}
	}
}
