package ub.scp2.managedBeans;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

import org.primefaces.model.chart.PieChartModel;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.jsf.FacesContextUtils;

import ub.scp2.entities.Submission;
import ub.scp2.entities.Task;
import ub.scp2.entities.TestResult;


/**
 * ReportBean.java - a Bean to control the Report view. 
 * 
 *
 */
@ManagedBean(name="reportBean")
@ViewScoped
public class ReportBean implements Serializable {
	
	private Task task;
	
	private List<Submission> submissions;
	
	private Submission selectedSubmission;
        
        private String path;
        private String taskFilesPath;
	
    @ManagedProperty(value="#{loginBean}")
	private LoginBean loginbean;

	/**
	 * Initialize the parameters required for the class
	 */
    @PostConstruct
    public void init() { 	
    	WebApplicationContext ctx =  FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
    	task = loginbean.getTask();
    	submissions = new ArrayList<Submission>(task.getSubmissions());
    	selectedSubmission = new Submission();
    	//user = loginbean.getUser();
        //taskbo = ctx.getBean(TaskBo.class);
        path = ctx.getServletContext().getRealPath("");
        
        taskFilesPath = path+"/WEB-INF/tasks/"+task.getSubject().getTitle()+"/"+
                task.getTitle()+"/";
    }
    
    
  
    public StreamedContent getAllFiles() {
        return getFile(taskFilesPath,task.getTitle()+".zip");
    }
    
    public StreamedContent submissionFiles(Submission s) {
        String submissionPath = taskFilesPath+"submissions/"+s.getUser().getUsername()+"/";
        return getFile(submissionPath, s.getUser().getUsername()+".zip");
    }
    
    private StreamedContent getFile(String folderDir, String filename){
        ByteArrayOutputStream baos = utils.ZipUtils.createZIP(folderDir);
        ByteArrayInputStream is = new ByteArrayInputStream(baos.toByteArray());

        StreamedContent file = new DefaultStreamedContent(is, "image/jpg", filename);
        return file;  
    }
    
    /**
     * Control function at the beginning of jsf
     */
    public void check(){
    	if(task == null){
	    	 try {
				FacesContext.getCurrentInstance().getExternalContext().redirect("teacher.xhtml");
			} catch (IOException e) {
				e.printStackTrace();
			}
    	}
    }
    
    /**
     * Responsible for creating the piechartmodel.
     * @param mark A type of Integer, represents the number of successes.
     * @return A type of PieChartModel. Represent in 100%
     */
    public PieChartModel buildChart(Integer mark){
        PieChartModel p = new PieChartModel();  
        p.set("Passed", mark);  
        p.set("Failed", 100-mark);
        return p;
    }
    
    /**
     * Redirect to the teacher view.
     * @return A type of String.
     */
    public String goBack() {  
 		return "teacher?faces-redirect=true";
     }
    
    
    
    //Getters and Setters
    
    /**
     * Retrieve a list with the result test for one submission
     * @return A List of TestResult type.
     */
    public List<TestResult> getResultList(){
    	List<TestResult> resultList = new ArrayList<TestResult>(selectedSubmission.getTestsResult());
    	return resultList;
    }

	/**
	 * Retrieve the private variable user
	 * @return A type Task
	 */
	public Task getTask() {
		return task;
	}

    /**
     * Set the private variable task
     * @param task A type of Task
     */
	public void setTask(Task task) {
		this.task = task;
	}

	/**
	 * Retrieve the private variable loginbean
	 * @return A type of LoginBean
	 */
	public LoginBean getLoginbean() {
		return loginbean;
	}

    /**
     * Set the private variable loginbean
     * @param loginbean A type of LoginBean
     */
	public void setLoginbean(LoginBean loginbean) {
		this.loginbean = loginbean;
	}

    /**
     * Retrieve a list submissions
     * @return A List of Submission type.
     */
	public List<Submission> getSubmissions() {
		return submissions;
	}

    /**
     * Set the list submissions
     * @param loginbean A List of Submission type
     */
	public void setSubmissions(List<Submission> submissions) {
		this.submissions = submissions;
	}

	/**
	 * Retrieve the private variable selectedSubmission
	 * @return A type of Submission
	 */
	public Submission getSelectedSubmission() {
		return selectedSubmission;
	}

    /**
     * Set the private variable selectedSubmission
     * @param selectedSubmission A type of Submission
     */
	public void setSelectedSubmission(Submission selectedSubmission) {
		this.selectedSubmission = selectedSubmission;
	}
}
