package org.yacos.tests.core;


import static org.junit.Assert.*;

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

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

import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.yacos.core.article.Article;
import org.yacos.core.article.IArticleManager;
import org.yacos.core.article.Preference;
import org.yacos.core.conferences.Conference;
import org.yacos.core.conferences.IConferenceManager;
import org.yacos.core.exceptions.ConferenceDoesntExistException;
import org.yacos.core.exceptions.PKAlreadyUsedException;
import org.yacos.core.exceptions.UserEMailAlreadyExistsException;
import org.yacos.core.users.IUserManager;
import org.yacos.core.users.User;

public class ArticleManagerTest {
	
	private static IArticleManager am;
	private static IConferenceManager cm;
	private static IUserManager um;
	private User author;
	private Conference conf;
	private int articleId;
	
	@BeforeClass
	public static void setUpManager() throws NamingException, PKAlreadyUsedException {
		Context context = new InitialContext();
		am = (IArticleManager) context.lookup("ArticleManagerBean/remote");
		um = (IUserManager) context.lookup("UserManagerBean/remote");
		cm = (IConferenceManager) context.lookup("ConferenceManagerBean/remote");
	}
	
	@Before
	public void setupArticleTest() throws PKAlreadyUsedException, UserEMailAlreadyExistsException{
		//ajout d'un user
		if (um.exists("max")){
			author = um.getUser("max");
		}else{
			author = um.addUser("max",User.hashPassword("pw"),"maxime","dagn","ipint", "e@e.fr");
		}
		//ajout d'une conf
		conf = cm.addConference("titi","desc conf","info en plus",new Date(),new Date(),new Date(),new Date(),new Date());
		assertEquals("titi", cm.getConference(conf.getId()).getTitle());;
		
		//ajout d'un article
		Article article = am.addArticle(
				"title",
				"topic",
				"url_article",
				author.getLogin(),
				new ArrayList<String>(),
				Article.State.SUMMARY,
				conf.getId());
		articleId = article.getId();
	}
	

	@After
	public void cleanup() throws ConferenceDoesntExistException{
	/*	List<Article> list = am.getArticles(conf.getId());
		for (Article article : list) {
			am.removeArticle(article.getId());
		}
		cm.remove(conf.getId());*/
	}
		
	@Test
	public void addArticleTest(){
		assertNotNull(am.getArticle(articleId));
		assertEquals("title", am.getArticle(articleId).getTitle());
	}
	
	@Test
	public void updateArticleTest(){
		Article article = am.getArticle(articleId); 
		article.setTitle("titre2");
		am.updateArticle(article);
		article = am.getArticle(articleId);
		assertNotNull(article);
		assertEquals("titre2", article.getTitle());
		assertEquals(articleId, article.getId());
	}
	
	@Test
	public void removeArticleTest(){
		am.removeArticle(articleId);
		assertFalse(am.existsArticle(articleId));
	}
	
	
	@Test
	public void getArticlesOfConfTest() throws Exception{
				
		Integer numberOfArticles = am.getArticles(conf.getId()).size();
		//ajout d'un article
		Article article = am.addArticle("title1","topic","url_article",author.getLogin(),new ArrayList<String>(),
				Article.State.SUMMARY,conf.getId());
		
		List<Article> list = am.getArticles(conf.getId());
		assertEquals(numberOfArticles+1, list.size());
		assertFalse("list not empty", list.isEmpty());
		
		assertEquals(article.getTitle(),list.get(list.size()-1).getTitle());
	
		am.removeArticle(article.getId());
	}
	
	@Test
	public void getArticleOfConfAndAuthor() throws ConferenceDoesntExistException{
		
		Integer numberOfArticles = am.getArticleOfAuthor(conf.getId(),author.getLogin()).size();
		//ajout d'un article
		Article article = am.addArticle("title","topic","url_article",author.getLogin(),new ArrayList<String>(),
				Article.State.SUMMARY,conf.getId());
		
		List<Article> list = am.getArticles(conf.getId());
		assertEquals(numberOfArticles+1, list.size());
		assertFalse("list not empty", list.isEmpty());
		assertEquals(article.getTitle(),list.get(list.size()-1).getTitle());
		am.removeArticle(article.getId());
	}
	
	@Test
	public void delegateArticleToRefereeTest(){
		
		
		
	}
	
	@Test
	public void assignArticleToPCMemberTest(){
		User member = um.getUser("max");
		am.assignArticleToPCMember(articleId,member.getLogin());
		List<User> list = um.getPCMemberForArticle(articleId);
		assertFalse(list.isEmpty());
	}
	
	@Test
	public void unassignArticleToPCMemberTest(){
		//TODO
	}
	
	
	@Test
	public void getArticleforMemberTest(){
		am.assignArticleToPCMember(articleId,"max");
		List<Article> list = am.getArticlesOfMember(conf.getId(), "max");
		assertFalse(list.isEmpty());
	
	}
	/*
	 * test des preferences
	 */
	@Test
	public void addAndGetPreferenceTest(){
		am.addPreference(articleId, "max", Preference.PreferenceType.LIKE);
		Preference pref = am.getPreferenceForUserAndArticle(articleId, "max");
		assertEquals(Preference.PreferenceType.LIKE, pref.getPreferenceType());
	}
	
	@Test
	public void updatePreferenceTest(){		
		Preference preference = am.addPreference(articleId, "max", Preference.PreferenceType.LIKE);
		preference.setPreferenceType(Preference.PreferenceType.INDIFFERENT);
		am.updatePreference(preference);
		preference = am.getPreferenceForUserAndArticle(articleId, "max");
		assertEquals(Preference.PreferenceType.INDIFFERENT, preference.getPreferenceType());
	}
	
	@Test
	public void removePreferenceTest(){
		am.addPreference(articleId, "max", Preference.PreferenceType.LIKE);
		am.removePreference(articleId, "max");
		assertNull(am.getPreferenceForUserAndArticle(articleId,"max"));
	}
	
	@Test
	public void getPreferenceForArticleTest(){
		am.addPreference(articleId, "max", Preference.PreferenceType.LIKE);
		List <Preference> list = am.getPreferencesForArticle(articleId);
		assertFalse("list vide", list.isEmpty());
	}
}
