package org.yacos.web.system.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.yacos.core.article.Article;
import org.yacos.core.article.IArticleManager;
import org.yacos.core.article.Article.State;
import org.yacos.core.conferences.Conference;
import org.yacos.core.conferences.IConferenceManager;
import org.yacos.core.evaluation.IEvaluationManager;
import org.yacos.core.evaluation.Report;
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;
import org.yacos.web.system.controller.NoConferenceSelectedException;
import org.yacos.web.system.form.UserBoardArticleBean;
import org.yacos.web.system.session.SessionService;

public class UserBoardController extends SimpleFormController {

    protected final Log logger = LogFactory.getLog(getClass());
    
    private IArticleManager articleManager;
	private IUserManager userManager;
	private IConferenceManager conferenceManager;
	private IEvaluationManager evaluationManager;
    
	public IArticleManager getArticleManager() {
		return articleManager;
	}

	public void setArticleManager(IArticleManager articleManager) {
		this.articleManager = articleManager;
	}

	public IUserManager getUserManager() {
		return userManager;
	}

	public void setUserManager(IUserManager userManager) {
		this.userManager = userManager;
	}

	public IConferenceManager getConferenceManager() {
		return conferenceManager;
	}

	public void setConferenceManager(IConferenceManager conferenceManager) {
		this.conferenceManager = conferenceManager;
	}

	public IEvaluationManager getEvaluationManager() {
		return evaluationManager;
	}

	public void setEvaluationManager(IEvaluationManager evaluationManager) {
		this.evaluationManager = evaluationManager;
	}

	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, NoConferenceSelectedException {
		
        logger.info("Returning UserBoard view");
        
        Map<String, Object> model = new HashMap<String, Object>();
        
        logger.info("Get the list of roles of an user");
        List<Role> listRole = userManager.getRolesForUser(SessionService.getInstance().getCurrentUserLogin());
        
        Integer numberChairman = 0;
        Integer numberPCMember = 0;
        Integer numberReferee = 0;
        Integer numberAuthor = 0;
        
        for (Role r : listRole) {
        	if (r.getType() == RoleType.CHAIRMAN)
        		numberChairman++;
        	else if (r.getType() == RoleType.PCMEMBER)
        		numberPCMember++;
        	else if (r.getType() == RoleType.REFEREE)
        		numberReferee++;
        	else if (r.getType() == RoleType.AUTHOR)
        		numberAuthor++;
        }
        
        model.put("numberChairman", numberChairman);
        model.put("numberPCMember", numberPCMember);
        model.put("numberReferee", numberReferee);
        model.put("numberAuthor", numberAuthor);
        model.put("listRole", listRole);
        
        logger.info("Get the list of articles of an author");
        List<Article> listAllArticle =  articleManager.getArticleOfAuthor(SessionService.getInstance().getCurrentUserLogin());
        Integer numberArticle = listAllArticle.size();
        
        // create Article bean from Article object
        List<UserBoardArticleBean> listAllArticleBean = new ArrayList<UserBoardArticleBean>();
        
        for (Article a : listAllArticle) {
        	UserBoardArticleBean ab = new UserBoardArticleBean();
        	ab.setAbstractText(a.getAbstractText());
        	ab.setTitle(a.getTitle());
        	ab.setTopic(a.getTopic());
        	ab.setId(a.getId());
        	ab.setState(a.getState());
        	ab.setSecondaryAuthors(a.getSecondaryAuthors());
        	ab.setURL_article(a.getURL_article());
        	ab.setConference(articleManager.getConferenceForArticle(a.getId()));
        	listAllArticleBean.add(ab);
        }
        	
        model.put("numberArticle", numberArticle);
        model.put("listAllArticle", listAllArticleBean);
        
        logger.info("Get the list of conferences of an user");
        List<Conference> listConfForUser = conferenceManager.getConferences(SessionService.getInstance().getCurrentUser());
        Integer numberConference = listConfForUser.size();
        model.put("numberConference", numberConference);
        model.put("listConfForUser", listConfForUser);
        
        logger.info("Get the list of article of all the conference for the user in PCMember");
        List<Article> listArticlePCMember = new ArrayList<Article>();
        List<Article> listArticleReferee;
        List<UserBoardArticleBean> listArticlePCMemberBean = new ArrayList<UserBoardArticleBean>();
        List<UserBoardArticleBean> listArticleRefereeBean = new ArrayList<UserBoardArticleBean>();
        List<Conference> listConfPCMember = new ArrayList<Conference>();
        
        Integer numberEvaluatedPCMember = 0;
        Integer numberNotEvaluatedPCMember = 0;
        
        for (Conference c : listConfForUser) {
        	if (userManager.hasRoleForConference(SessionService.getInstance().getCurrentUserLogin(), RoleType.PCMEMBER, c.getId()))
        		listConfPCMember.add(c);
        }
        
        for (Conference c : listConfPCMember) {
        	listArticlePCMember.addAll(articleManager.getArticlesOfMember(c.getId(), SessionService.getInstance().getCurrentUserLogin()));
        }
        
        for (Article a : listArticlePCMember) {
        	UserBoardArticleBean ab = new UserBoardArticleBean();        	
        	ab.setAbstractText(a.getAbstractText());
        	ab.setTitle(a.getTitle());
        	ab.setTopic(a.getTopic());
        	ab.setId(a.getId());
        	ab.setState(a.getState());
        	ab.setSecondaryAuthors(a.getSecondaryAuthors());
        	ab.setURL_article(a.getURL_article());
        	ab.setConference(articleManager.getConferenceForArticle(a.getId()));
        	List<User> referee = userManager.getRefereesOfPcMemberForArticle(SessionService.getInstance().getCurrentUserLogin(), a.getId());
        	if (referee != null) {
        		ab.setReferee(referee);
        	}
        	else {
        		ab.setReferee(null);
        	}
        	
        	Report rpt = evaluationManager.getReportforArticleAndReferee(a.getId(), SessionService.getInstance().getCurrentUserLogin());
			if (rpt == null) {
				if (referee != null) {
					for (User r : referee) {
						Report tmp = evaluationManager.getReportforArticleAndReferee(a.getId(), r.getLogin());
						if (tmp != null) {
							ab.setEvaluated(true);
							break;
						}
					}
				}
				else {
					ab.setEvaluated(false);
				}
				
				if (! a.getState().equals(State.ACCEPTED) && ! a.getState().equals(State.REJECTED) && referee == null)
					numberNotEvaluatedPCMember++;
			}
			else {
				ab.setEvaluated(true);
				numberEvaluatedPCMember++;
			}
        	listArticlePCMemberBean.add(ab);
        }
        
        listArticleReferee = articleManager.getArticlesOfReferee(SessionService.getInstance().getCurrentUserLogin());
        
        Integer numberEvaluatedReferee = 0;
        Integer numberNotEvaluatedReferee = 0;
        
        for (Article a : listArticleReferee) {
        	UserBoardArticleBean ab = new UserBoardArticleBean();
        	
        	Report rpt = evaluationManager.getReportforArticleAndReferee(a.getId(), SessionService.getInstance().getCurrentUserLogin());
			if (rpt == null) {
				ab.setEvaluated(false);
				if (! a.getState().equals(State.ACCEPTED) && ! a.getState().equals(State.REJECTED))
					numberNotEvaluatedReferee++;
			}
			else {
				ab.setEvaluated(true);
				numberEvaluatedReferee++;
			}
        	
        	ab.setAbstractText(a.getAbstractText());
        	ab.setTitle(a.getTitle());
        	ab.setTopic(a.getTopic());
        	ab.setId(a.getId());
        	ab.setState(a.getState());
        	ab.setSecondaryAuthors(a.getSecondaryAuthors());
        	ab.setURL_article(a.getURL_article());
        	ab.setConference(articleManager.getConferenceForArticle(a.getId()));
        	listArticleRefereeBean.add(ab);
        }        
        
        model.put("numberEvaluatedReferee", numberEvaluatedReferee);
        model.put("numberNotEvaluatedReferee", numberNotEvaluatedReferee);
        model.put("numberEvaluatedPCMember", numberEvaluatedPCMember);
        model.put("numberNotEvaluatedPCMember", numberNotEvaluatedPCMember);
        model.put("listArticlePCMember", listArticlePCMemberBean);
        model.put("numberArticlePCMember", listArticlePCMember.size());     
        model.put("listArticleReferee", listArticleRefereeBean);
        model.put("numberArticleReferee", listArticleReferee.size());
        
        logger.info("Get the number of conferences the user can create");
        Integer numberCreationTokens = conferenceManager.conferenceCreationTokens(SessionService.getInstance().getCurrentUserLogin());
        model.put("numberCreationTokens", numberCreationTokens);
        
        return new ModelAndView("userBoard", model);
    }
}