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


import java.util.List;

import javax.ejb.Stateless;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.yacos.core.article.IArticleManager;
import org.yacos.core.conferences.IConferenceManager;
import org.yacos.core.users.IUserManager;

/**
 * @author christiancorsano
 *
 */
@Stateless
public class EvaluationManagerBean implements IEvaluationManager {
	@PersistenceContext
	EntityManager em;
	
	protected final Log logger = LogFactory.getLog(getClass());
	 
	private IConferenceManager cm;
	private IArticleManager am;
	private IUserManager um;
	
	private IConferenceManager getConferenceManager(){
		Context context;
		try {
			context = new InitialContext();
			cm = (IConferenceManager)context.lookup("ConferenceManagerBean/remote");
		} catch (NamingException e) {
			logger.error(e.getMessage());
		}
		return cm;
	}
	private IArticleManager getArticleManager(){
		Context context;
		try {
			context = new InitialContext();
			am = (IArticleManager)context.lookup("ArticleManagerBean/remote");
		} catch (NamingException e) {
			logger.error(e.getMessage());
		}
		return am;
}
	private IUserManager getUserManager(){
			Context context;
			try {
				context = new InitialContext();
				um = (IUserManager)context.lookup("UserManagerBean/remote");
			} catch (NamingException e) {
				logger.error(e.getMessage());
			}
			return um;
	}

	
	@SuppressWarnings("unchecked")
	public List<Criterion> getCriterions(int confId){	
		//Query q = em.createQuery("from Criterion");
		Query query = em.createQuery("from Criterion where conference_id = ?");
		query.setParameter(1, confId);		 		
		return query.getResultList();
		//return q.getResultList();
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.yacos.core.evaluation.IEvaluationManager#getCriterions()
	 */
	@SuppressWarnings("unchecked")
	public List<Criterion> getCriterions() {
		Query query = em.createQuery("from Criterion");
		return query.getResultList();
	}
	
	

	public Criterion addCriterion(String name, Integer min_rating,
			Integer max_rating, int confId) {	
		cm = getConferenceManager();	
		Criterion crit = new Criterion();
		crit.setName(name);
		crit.setMin_rating(min_rating);
		crit.setMax_rating(max_rating);
		crit.setConference(cm.getConference(confId));
		em.persist(crit);
		em.flush();
		return crit;
	}

	public void updateCriterion(Criterion criterion) {
		em.merge(criterion);
		em.flush();
	}

	public void removeCriterion(int criterionId) {
		Criterion criterion = this.getCriterion(criterionId);
		em.remove(criterion);
	}
	
	public Criterion getCriterion(int criterionId) {
		return em.find(Criterion.class, criterionId);
	}


	/**
	 * methodes du Report 
	 */
	
	public Report addReport(int articleId, String commentPCMember, String commentAuthor, List<Rating> ratings, 
			String refereeLogin) {
		um = getUserManager();
		am = getArticleManager();
		
		Report report = new Report();
		report.setReferee(um.getUser(refereeLogin));
		report.setArticle(am.getArticle(articleId));
		report.setCommentPCMember(commentPCMember);
		report.setCommentAuthor(commentAuthor);
		report.setRatings(ratings);
		
		//Report report = new Report("dsd",commentAuthor,ratings,um.getUser(refereeLogin),am.getArticle(articleId)); 
		em.persist(report);
		em.flush();
		return report;
	}

	public void updateReport(Report report) {
		em.merge(report);
		em.flush();
	}
	
	public void removeReport(int reportId) {
		Report report = this.getReport(reportId);
		em.remove(report);
		
	}
	
	public Report getReport(int reportId){
		Report report = em.find(Report.class, reportId);
		return report;
	}
	
	public Report getReportforArticleAndReferee(int articleId, String refereeLogin) {
		Query q = em.createQuery("from Report r where article_id= ? and referee_id= ?");
		q.setParameter(1, articleId);
		q.setParameter(2, refereeLogin);
		return (Report) q.getSingleResult();
	}

	@SuppressWarnings("unchecked")
	public List<Report> getReportsForArticle(int articleId) {
		Query q = em.createQuery("from Report r where article_id= ?");
		q.setParameter(1, articleId);
		return q.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Report> getReportsForReferee(String refereeLogin) {
		Query q = em.createQuery("from Report r where referee_id= ?");
		q.setParameter(1, refereeLogin);
		return q.getResultList();
	}
	
	/*
	 * rating methods
	 */
	
	public Rating addRating(Integer value, Criterion criterion, Report report) {
		Rating rating = new Rating(value,criterion,report);
		em.persist(rating);
		em.flush();
		return rating;
	}
	
	@SuppressWarnings("unchecked")
	public List<Rating> getRatingForReport(Integer reportId){
		Query q = em.createQuery("select r.ratings from Report r where r.id=?");
		q.setParameter(1, reportId);
		return q.getResultList();
	}
	public void removeRating(Criterion criterion, Report report) {
		Rating rating = em.find(Rating.class, new RatingPK(criterion,report));
		em.remove(rating);
		em.flush();
	}
	
	public Rating updateRating(Rating rating) {
		em.merge(rating);
		em.flush();
		return rating;
	}
	
}
