package org.yacos.tests.core;

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

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.conferences.Conference;
import org.yacos.core.conferences.IConferenceManager;
import org.yacos.core.evaluation.Criterion;
import org.yacos.core.evaluation.IEvaluationManager;
import org.yacos.core.evaluation.Rating;
import org.yacos.core.evaluation.Report;
import org.yacos.core.exceptions.PKAlreadyUsedException;
import org.yacos.core.users.IUserManager;

@SuppressWarnings("unused")
public class EvaluationManagerTest {

	private static IEvaluationManager em;
	private static IArticleManager am;
	private static IConferenceManager cm;
	private static IUserManager um;
	private int confId;
	private Article article;
	
	@BeforeClass
	public static void setUpManager() throws NamingException, PKAlreadyUsedException {
		Context context = new InitialContext();
		cm = (IConferenceManager) context.lookup("ConferenceManagerBean/remote");
		em = (IEvaluationManager) context.lookup("EvaluationManagerBean/remote");
		am = (IArticleManager) context.lookup("ArticleManagerBean/remote");
		um = (IUserManager) context.lookup("UserManagerBean/remote");
	}
	
	@Before
	public void initDB() throws Exception{
		um.addUser("evaluationManagerTest", "pw", "first", "last", "yacos", "evaluationManagerTest@yacos.com");
		cm.addConferenceCreationToken("evaluationManagerTest");
		Conference conf = cm.addConference("titre","evaluationManagerTest","desc conf","info en plus",new Date(),new Date(),new Date(),new Date(),new Date());
		confId = conf.getId();
		
		article = am.addArticle("title article max","topic","Abstract", "url_article",
				"evaluationManagerTest",	new ArrayList<String>(), Article.State.SUBMITED,	confId);
		//article = am.getArticle(1); 
	}
	
	@After
	public void cleanDB(){
		am.removeArticle(article.getId());
		um.removeUser("evaluationManagerTest");
		cm.remove(confId);
	}
	
	@Test
	public void add_et_getCriterionsTest() {
		Criterion crit = em.addCriterion("name", 0, 4, confId);
		assertNotNull(crit);
		assertEquals(crit.getName(), em.getCriterion(crit.getId()).getName());
	}
	
	@Test
	public void getCriterionsTest() throws NamingException{
		em.addCriterion("name", 0, 4, confId);
		List<Criterion> list = em.getCriterions(confId);
		assertFalse("liste vide",list.isEmpty());
	}
	
	@Test
	public void updateCriterionTest(){
		Criterion crit = em.addCriterion("name", 0, 4, confId);
		crit.setName("autre");
		em.updateCriterion(crit);
		crit = em.getCriterion(crit.getId());
		assertEquals("autre", crit.getName());
	}
	
	@Test
	public void removeCriterion(){
		Criterion crit = em.addCriterion("name", 0, 4, confId);
		em.removeCriterion(crit.getId());
	}
	
	@Test
	public void AddReportTest(){
		List<Rating> ratings = new ArrayList<Rating>();
		Report report = em.addReport(article.getId(), "commentPCMember", "commentAuthor", ratings, "max");
		
		//assertNotNull(em.getReportforArticleAndReferee(article.getId(), "max"));
		assertEquals(report.getCommentAuthor(), em.getReport(report.getId()).getCommentAuthor());
	}
	
	@Test
	public void updateReportTest(){
		Report report = em.addReport(article.getId(), "commentPCMember", "commentAuthor", new ArrayList<Rating>(), "max");
		report.setCommentPCMember("autre");
		em.updateReport(report);
		assertEquals("autre", em.getReport(report.getId()).getCommentPCMember());
	}
	
	@Test
	public void removeReportTest(){
		Report report = em.addReport(article.getId(), "report a virer", "commentAuthor", new ArrayList<Rating>(), "max");
		em.removeReport(report.getId());
		assertNull(em.getReport(report.getId()));
	}	
	
	
	@Test
	public void getReportforArticleAndRefereeTest(){
		Report report = em.addReport(article.getId(), "report a virer", "commentAuthor", new ArrayList<Rating>(), "max");
		Report report2 =em.getReportforArticleAndReferee(article.getId(), "max");
		assertEquals(report.getId(), report2.getId());
	}

	
	@Test
	public void getReportsForArticleTest(){
			em.addReport(article.getId(), "report a virer", "commentAuthor", new ArrayList<Rating>(), "admin");
			em.addReport(article.getId(), "report a virer", "commentAuthor", new ArrayList<Rating>(), "max");
			List <Report> list = em.getReportsForArticle(article.getId());
			assertTrue(list.size() == 2);
			
	}
	@Test
	public void getReportsForRefereeTest(){
		em.addReport(article.getId(), "report a virer", "commentAuthor", new ArrayList<Rating>(), "admin");
		em.addReport(article.getId(), "report a virer", "commentAuthor", new ArrayList<Rating>(), "max");
		List <Report> list = em.getReportsForReferee("max");
		assertFalse(list.isEmpty());
		//assertTrue(list.size() == 1);
	}
	
	@Test
	public void getRatingsFromReportTest(){
		Criterion criterion = em.addCriterion("crit�re1", 0, 3, confId);
		Report report = em.addReport(article.getId(), "report a virer", "commentAuthor", new ArrayList<Rating>(), "max");
		em.addRating(2,criterion.getId(),report.getId());
		assertFalse(em.getRatingForReport(report.getId()).isEmpty());
		em.removeRating(criterion, report);
	}
	
	@Test
	public void updateRatingTest(){
		Criterion criterion = em.addCriterion("crit�re1", 0, 3, confId);
		Report report = em.addReport(article.getId(), "report a virer", "commentAuthor", new ArrayList<Rating>(), "max");
		Rating rating = em.addRating(2,criterion.getId(),report.getId());
		rating.setValue(1);
		em.updateRating(rating);
		rating = em.getRatingForReport(report.getId()).get(1);
		assertEquals(1, rating.getValue());
		em.removeRating(criterion, report);	
	}
	
}
