package ub.scp2.managedBeans;

import infoObjects.InfoError;
import infoObjects.InfoTarea;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import java.io.InputStream;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.FlowEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.TabChangeEvent;
import org.primefaces.event.UnselectEvent;
import org.primefaces.model.UploadedFile;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.jsf.FacesContextUtils;

import ub.scp2.bo.LanguajeBo;
import ub.scp2.bo.TaskBo;
import ub.scp2.bo.FileTaskBo;
import ub.scp2.bo.UserBo;
import ub.scp2.entities.Languaje;
import ub.scp2.entities.Subject;
import ub.scp2.entities.Task;
import ub.scp2.entities.FileTask;
import ub.scp2.entities.Test;

import utils.ConstantsErr;
import utils.RMIServices;

/**
 * TaskBean.java -a Bean to control the new Task view.
 *
 *
 */
@ManagedBean(name = "taskBean")
@ViewScoped
public class TaskBean implements Serializable, ConstantsErr {

    /**
     *
     */
    private static final long serialVersionUID = -4048141595404078722L;
    private TaskBo taskbo;
    private FileTaskBo filetaskbo;
    private UserBo userbo;
    private LanguajeBo languajebo;

    private Task task;
    private FileTask fileTask;
    private Date today;
    private Languaje languaje;
    private Integer languajeId;
    private String langExt;

    private boolean rSubmitDisabled;
    private boolean nSubmitDisabled;
    private boolean mSubmitDisabled;
    private boolean rawCode;

    private List<FileTask> docFiles;
    private FileTask makefile;
    private InputStream docInputStream;

    private List<ArgumentPreset> argsPresets;
    private List<ArgumentPreset> selectedPresets;
    private List<String> mimeTypes;
    private List<String> selectedTypes;
    private String extraArguments;
    private String codigo;
    private String mainFilename;
    private String path;

    private utils.FileManager fileman;

    @ManagedProperty(value = "#{loginBean}")
    private LoginBean loginbean;


    public TaskBean() {
    }

    /**
     * Initialize the parameters required for the class
     */
    @PostConstruct
    public void init() {
        WebApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());

        taskbo = ctx.getBean(TaskBo.class);
        userbo = ctx.getBean(UserBo.class);
        filetaskbo = ctx.getBean(FileTaskBo.class);
        languajebo = ctx.getBean(LanguajeBo.class);
        
        docFiles = new ArrayList();
        task = new Task();
        task.setHasCodeTeacher(true);
        task.setFiles(new java.util.HashSet<FileTask>());
        //languaje = new Languaje();
        fileTask = new FileTask();
        fileTask.setTask(task);
        today = new Date();
        rSubmitDisabled = true; rSubmitDisabled = true;

        path = ctx.getServletContext().getRealPath("");
        List<String[]> argsPres = taskbo.getPresetArguments(path);
        argsPresets = new ArrayList();
        for (String[] s: argsPres){
            argsPresets.add(new ArgumentPreset(s[2], s[1], Integer.parseInt(s[0])));
        }
        mimeTypes = new ArrayList();
        mimeTypes.add("pdfs");
        mimeTypes.add("images");
        mimeTypes.add("sounds");
        mimeTypes.add("videos");
    }
    
    /**
     * Error print on website.
     * @param text Error message
     */
    private void errorMsg(String text){
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, text, "");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }


    /**
     * Save the new Task and redirect to the test view. If teacher select don't
     * upload code, the code is ' '.
     *
     * @return A type String, this is a redirect instruction.
     * @throws NotBoundException
     * @throws RemoteException
     * @throws MalformedURLException
     */
    public String saveNewTask() throws MalformedURLException, RemoteException, NotBoundException {
        if (task.getNameFile() == null)
            task.setNameFile(getFilename());
        
        task.setUser(userbo.getUserByUsername(getRemoteUsername()));
        //task.setLanguaje(languajebo.getLanguajeById(languajeId));

        if (task.isHasCodeTeacher()) {           
            if (!fileman.moveAllTempToSaved()){errorMsg("couldn't move files"); return "";}

            java.util.Set<FileTask> tmpFiles = task.getFiles();
            task.setFiles(null);
            
            taskbo.saveTask(task);
            
            for (FileTask tf : tmpFiles){
                filetaskbo.saveFileTask(tf);
            }
            task.setFiles(tmpFiles);
            
        } else {
            if (task.isHasMakefile()){
                try {
                    fileman.cleanTempPath();
                    fileman.createTempFile("makefile", makefile.getContent());
                    if (fileman.getFileMime()[0].equals("text")){
                        fileman.moveAllTempToSaved();
                        task.setNameFile(mainFilename);
                        
                        task.removeAllFiles();
                        
                        taskbo.saveTask(task);
                        filetaskbo.saveFileTask(makefile);
                        task.addFile(makefile);
                    } else {
                        fileman.cleanTempPath();
                    }
                } catch (IOException e) {
                    errorMsg("Error saving task");
                    return "";
                }
            } else {
                task.setNameFile(getFilename());
                taskbo.saveTask(task);
            }
        }

        task.setTests(new java.util.HashSet<Test>());
        loginbean.setTask(task);
        System.out.println("DEEEEEEEEEEEEEEEEEEEEEEEBUG");
        System.out.println("ID TAREA: " + task.getTaskId());
        if (!RMIServices.isConnected()) {
            RMIServices.connectRMI();
        }
        
        
        ArrayList<byte[]> contents = new ArrayList<byte[]>();
        for (FileTask f : task.getFiles()){
            contents.add(f.getContent());
        }
        InfoTarea infoTarea = new InfoTarea(task.getTaskId(), contents, task.getFilenameArray(),task.getCompilerArguments(), task.getLanguaje(), task.isHasCodeTeacher(), task.isHasMakefile(),task.getNameFile());
        
        RMIServices.securityNewTask(infoTarea);

        return "addtests?faces-redirect=true";
    }

    /**
     * Used when checking raw code. Just 1 file.
     * 
     * @param actionEvent event
     */
    public void rawCheckCode(ActionEvent actionEvent) throws RemoteException, MalformedURLException, NotBoundException, IOException {
        String fil = fileTask.getFilename();
        if (fil == null || fil.equals("")){
            errorMsg("Please, enter a filename");
            rSubmitDisabled = true; return;
        }
        if (this.codigo == null || this.codigo.equals("")){
            errorMsg("Please, enter a code");
            rSubmitDisabled = true; return;
        }
        fileman.cleanTempPath();
        if (!fileman.createTempFile(fileTask.getFilename(),this.codigo)){
            fileman.cleanTempPath();
            errorMsg("An error ocurred saving your files");
            rSubmitDisabled = true; return;
        }
        byte[] codigoByte = this.codigo.getBytes();
        
        fileTask.setContent(codigoByte);

        task.removeAllFiles();
        task.addFile(fileTask);
        task.setNameFile(getFilename());
        
        rSubmitDisabled = !checkCode(actionEvent);
    }
    
    /**
     * Used when checking uploaded multiple files.
     * 
     * @param actionEvent event
     */
    public void multipleCheckCode(ActionEvent actionEvent) throws RemoteException, MalformedURLException, NotBoundException, IOException {
        if (docFiles.size() <= 0){
            errorMsg("Upload at least 1 file");
            mSubmitDisabled = true; return;
        }
        
        if (mainFilename == null || mainFilename.equals("")){
            errorMsg("Please, select file where main is located");
            mSubmitDisabled = true; return;
        }
        
        if (task.isHasMakefile()) {
            boolean makefileFound = false;
            boolean executableAreadyExists = false;

            for (FileTask uf: docFiles) {
                if (uf.getFilename().toLowerCase().equals("makefile"))
                    makefileFound = true;
                if (uf.getFilename().toLowerCase().equals(mainFilename.toLowerCase()))
                    executableAreadyExists = true;
            }
            if (!makefileFound) {
                errorMsg("Please, upload makefile");
                mSubmitDisabled = true; return;
            }
            if (executableAreadyExists) {
                errorMsg("'"+mainFilename+"' should be created after executing makefile, not before");
                mSubmitDisabled = true; return;
            }
        }
        
        System.out.println("CleanTemp: "+fileman.cleanTempPath());
        
        for (FileTask uf: docFiles){
            if (fileman.createTempFile(uf.getFilename(),uf.getContent())){
                String[] mimeType = fileman.getFileMime();
                if (mimeType[0].equals("application") && !mimeType[1].equals("pdf")) {
                    errorMsg("File '" + uf.getFilename() + "' not admitted: " + mimeType[0]+"-"+mimeType[1]);
                    fileman.cleanTempPath();
                    mSubmitDisabled = true; return;
                }
            } else {
                fileman.cleanTempPath();
                errorMsg("An error ocurred saving your files");
                mSubmitDisabled = true; return;
            }
        }

        task.removeAllFiles();
        for (FileTask uf: docFiles)
            task.addFile(uf);
        
        task.setNameFile(mainFilename);
        
        mSubmitDisabled = !checkCode(actionEvent);
    }
    
    /**
     * Checking code compiling it. Called by 'rawCheckCode' and 'multipleCheckCode'
     * @return no error?
     */
    private boolean checkCode(ActionEvent actionEvent) throws RemoteException, MalformedURLException, NotBoundException {
        int fileType = 0;
        for (int i=0; i<mimeTypes.size(); i++)
            if (this.selectedTypes.contains(mimeTypes.get(i)))
                fileType += Math.pow(2, i);
        task.setValidFiles(fileType);
        
        task.setUser(userbo.getUserByUsername(getRemoteUsername()));
        //task.setLanguaje(languajebo.getLanguajeById(languajeId));
        //List<String> result = taskbo.compile(task);
        if (!RMIServices.isConnected()) {
            RMIServices.connectRMI();
        }

        ArrayList<byte[]> contents = new ArrayList<byte[]>();
        for (FileTask f : task.getFiles()){
            contents.add(f.getContent());
        }
        InfoTarea infoTarea = new InfoTarea(task.getTaskId(), contents, task.getFilenameArray(),task.getCompilerArguments(), task.getLanguaje(), task.isHasCodeTeacher(), task.isHasMakefile(),task.getNameFile());
        
        InfoError infoError = RMIServices.securityCheckCode(infoTarea);
        taskbo.cleanup(task);

        if (infoError.getError() == ERROR_OK) {
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Compiled correctly", "");
            FacesContext.getCurrentInstance().addMessage(null, msg);
            return true;
        } else if(infoError.getError() == ERROR_LIBRARY){
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Compilation errors: Not allowed libraries detected", "");
            FacesContext.getCurrentInstance().addMessage(null, msg);
            return false;
        }else {
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Compilation errors " + infoError.getError() + "\n" + infoError.getErr(), "");
            FacesContext.getCurrentInstance().addMessage(null, msg);
            return false;
        }
    }
    
    /**
     * Handle file when it's uploaded. File will be added to "docFiles" or it
     * will be added to this.makefile if its a makefile and teacher won't be
     * uploading code
     */
    public synchronized void handleFileUpload(FileUploadEvent event){      
        try {
            if (task.isHasCodeTeacher()){
                mSubmitDisabled=true;
                UploadedFile f = event.getFile();

                FileTask ft = new FileTask();
                ft.setTask(task);
                ft.setFilename(f.getFileName());
                ft.setContent(f.getContents());

                if (f.getFileName().toLowerCase().equals("makefile")) {
                    if (task.isHasMakefile())
                        ft.setShared(true);
                    else
                        return;
                }

                synchronized(docFiles){
                    docFiles.add(ft);
                }
            } else {
                UploadedFile f = event.getFile();

                if (f.getFileName().toLowerCase().equals("makefile")) {
                    makefile = new FileTask();
                    makefile.setShared(true);
                    makefile.setTask(task);
                    makefile.setFilename(f.getFileName());
                    makefile.setContent(f.getContents());
                } else
                    makefile = null;

            }
        } catch (Exception x) {
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_FATAL, x.getClass().getName(), x.getMessage());
            FacesContext.getCurrentInstance().addMessage(null, message);
        }
    }
    
    
    
    /**
     * Clear update files. It removes the saved updated file list.
     */
    public void clearufile(){
        docFiles.clear();
        mSubmitDisabled=true;
    }
    
    /**
     * Redirect to the teacher view
     * @return A type of String, this reference to the redirection instruction.
     */
    public String goTeacherView() {
        return "teacher?faces-redirect=true";
    }
    
   public String onFlowProcess(FlowEvent event) {
        //Field validation for the General step
        if ("general".equals(event.getOldStep())) {

            //End date cannot be before Start date
            if (task.getEndDate().before(task.getStartDate())) {
                FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "End date must be after Start Date.", "");
                FacesContext.getCurrentInstance().addMessage(null, msg);
                return event.getOldStep();
            }
        }
        return event.getNewStep();
    }
    
    /**
     * Disable the Save Option
     */
    public void onCodeChanged() {
        rSubmitDisabled = true;
    }
    
    /**
     * Disable the Save Option
     */
    public void onMainFileChanged() {
        mSubmitDisabled = true;
    }
    
    /**
     * Control when Language Change, language asigned to the task
     */
    public void onLanguageChanged() {
        task.setLanguaje(languajebo.getLanguajeById(languajeId));
        task.setCompilerArguments("");
        task.setHasMakefile(false);
        langExt = languajebo.getLanguajeById(languajeId).getFileExtension();
        
        selectedPresets = new ArrayList<ArgumentPreset>();
        extraArguments = "";
        
        fileman = new utils.FileManager(path, task.getSubject().getTitle(), task.getTitle(), userbo.getUserByUsername(getRemoteUsername()).getUsername(), false);
    }
    
    /**
     * When changing "send code" method. Possible methods:
     * Raw code, multiple codes, don't upload files
     * @param event 
     */
    public void onSendCodeChange(TabChangeEvent event){
        String title = event.getTab().getTitle();
        if (title.equals("Input raw code")){
            this.task.setHasCodeTeacher(true);
        } else if(title.equals("Upload files")) {
            this.task.setHasCodeTeacher(true);
        } else {
            this.task.setHasCodeTeacher(false);
        }
    }
    
    /**
     * Retrieve the Remote User.
     *
     * @return
     */
    public String getRemoteUsername() {
        FacesContext fc = FacesContext.getCurrentInstance();
        ExternalContext ec = fc.getExternalContext();
        return ec.getRemoteUser();
    }

    /**
     * Retrieve the List of Languages
     *
     * @return A type List of Language
     */
    public List<Languaje> getLanguajeList() {
        return languajebo.getLanguajeList();
    }


    /**
     * Retrieve the List of Subject
     *
     * @return A type List of Subject
     */
    public List<Subject> getSubjectList() {
        ArrayList<Subject> blah = new ArrayList<Subject>(loginbean.getUser().getSubjects());
        return blah;
    }


    

    /**
     * It creates the "preview" of the compile command used in tab "compiler".
     * This also saves the full arguments sentence into the object "task"
     * @return preview of compile command used
     */
    public String updateTaskArguments() {
        String text = "";
        if (task.isHasMakefile()) text = "make ";
        else
            switch (task.getLanguaje().getLanguajeId()) {
                case 1: //c
                    text = "gcc <file_in> -o <file_out> ";
                    break;
                case 2: // java
                    text = "javac <file_in> ";
                    break;
                case 3: // python
                    text = "python <file_in> ";
                    break;
            }
        String args = "";
        // load argumentsPresets selected
        if (selectedPresets!=null)
            for (ArgumentPreset s: selectedPresets){
                if (!args.equals(""))
                    args += " ";
                args += s.getCode();
            }
        
        // load extaArgumments written
        if (this.extraArguments != null && !this.extraArguments.equals("")){
            if (!args.equals(""))
                args += " ";
            args += this.extraArguments;
        }
        // Also it saves the full argument sentence.
        this.task.setCompilerArguments(args);

        return text+args;
    }


    /**
     * Internal class containing information about an argument.
     * It contains a description about what is this, a language id to know which
     * language accepts this arg., and the library call code.
     */
    public class ArgumentPreset implements Serializable{
        public String code, descriptor;
        public int languajeId;
        public ArgumentPreset(String code, String descriptor, int languajeId) {
            this.code = code;
            this.descriptor = descriptor;
            this.languajeId = languajeId;
        }
        public String getCode() {
            return code;
        }
        public String getDescriptor() {
            return descriptor;
        }
        public int getLanguageId() {
            return languajeId;
        }
    }
    
   
    // ###################################################
    // ############# MODIFIED GETTERS & SETTERS ##########
    // ###################################################

    
    /**
     * Get a list of arguments availables for the language we'll be using
     *
     * @return List of ArgumentPreset
     */
    public List<ArgumentPreset> getArgsPresets() {
        List<ArgumentPreset> l = new ArrayList();
        for (ArgumentPreset ap: argsPresets)
            if (ap.languajeId == task.getLanguaje().getLanguajeId())
                l.add(ap);
        return l;
    }

    /**
     * Set the private variable argsPresets
     *
     * @param argsPresets A list of ArgumentPreset
     */
    public void setArgsPresets(List<ArgumentPreset> argsPresets) {
        this.argsPresets = argsPresets;
    }
    
    /**
     * Saves to fileTask the filename entered by the user + the extension of the 
     * language.
     * @param filename name of the file without extension 
     */
    public void setFilename(String filename) {
        fileTask.setFilename(filename+langExt);
    }
    
    /**
     * Returns the filename from the fileTask excluding the extension.
     * @return String containing the filename with no extensions
     */
    public String getFilename(){
        String fil = fileTask.getFilename();
        if (fil == null){
            return null;
        }
        return fil.substring(0, fil.lastIndexOf("."));
    }

    /**
     * Returns a list of those uploaded files which are selected as shared to the students.
     * @return List of shared uploaded files
     */
    public List<FileTask> getSharedDocFiles() {
        List<FileTask> lft = new ArrayList();
        for (FileTask ft:docFiles)
            if (ft.isShared())
                lft.add(ft);
        
        return lft;
    }
    
    /**
     * Won't save anything. sharedDocFiles will be added or deleted by using
     * addSharedFile, remSharedFile or toogleSharedFile
     * @param sharedDocFiles 
     */
    public void setSharedDocFiles(List<FileTask> sharedDocFiles) {}
    
    /**
     * Mark the FileTask as shared.
     * @param event JSF event containing a FileTask
     */
    public void addSharedFile(SelectEvent event) {
        FileTask ft = (FileTask) event.getObject();
        ft.setShared(true);
    }

    /**
     * Unmark the FileTask as shared. If this is a makefile it won't be unmarked.
     * @param event JSF event containing a FileTask.
     */
    public void remSharedFile(UnselectEvent event) {
        FileTask ft = (FileTask) event.getObject();
        if (!ft.getFilename().toLowerCase().equals("makefile"))
            ft.setShared(false);
    }
    
    /**
     * Check all uploaded files and mark or unmark all of them as shared.
     * Makefile will be always marked.
     * @param event JSF event.
     */
    public void toogleSharedFile(org.primefaces.event.ToggleSelectEvent event) {
        for (FileTask ft:docFiles)
            if (ft.getFilename().toLowerCase().equals("makefile"))
                ft.setShared(true);
            else
                ft.setShared(event.isSelected());
    }
    
    /**
     * Returns the list of uploaded files that have the language extension: .c, .java or .py
     * @return Uploaded files
     */
    public List<FileTask> getDocFilesFiltered() {
        List<FileTask> l = new ArrayList();
        for (FileTask uf: docFiles)
            if (uf.getFilename().endsWith(langExt))
                l.add(uf);
        return l;
    }
    
    /**
     * Set the executable filename into the private variable "mainFilename".
     * No extensions will be saved.
     * @param mainFilename 
     */
    public void setMainFilename(String mainFilename) {
        if (task.isHasMakefile()){
            this.mainFilename = mainFilename; //El mainFilename entrado no tiene extension en este caso
            return;
        }
        // Eliminamos extension: el ejecutable no tendra extension
        int i = mainFilename.lastIndexOf('.');
        if (i>=0)
            this.mainFilename = mainFilename.substring(0, i);
        else
            this.mainFilename = mainFilename;
    }
    
    /**
     * Gets the executable filaname.
     * @return 
     */
    public String getMainFilename() {
        return mainFilename;
    }
    
    // ###########################################
    // ############# GETTERS & SETTERS ###########
    // ###########################################
    
    /**
     * Retrieve the private variable today
     *
     * @return A type Date
     */
    public Date getToday() {
        return today;
    }
    
    /**
     * Retrieve the private variable languajeId
     *
     * @return A type Integer
     */
    public Integer getLanguajeId() {
        return languajeId;
    }

    /**
     * Set the private variable languajeId
     *
     * @param languajeId A type of Integer
     */
    public void setLanguajeId(Integer languajeId) {
        this.languajeId = languajeId;
    }

    /**
     * Retrieve the private variable rSubmitDisabled
     *
     * @return A type boolean
     */
    public boolean getRSubmitDisabled() {
        return rSubmitDisabled;
    }

    /**
     * Set the private variable rSubmitDisabled
     *
     * @param rSubmitDisabled A type of boolean
     */
    public void setRSubmitDisabled(boolean rSubmitDisabled) {
        this.rSubmitDisabled = rSubmitDisabled;
    }
    
    /**
     * Retrieve the private variable nSubmitDisabled
     *
     * @return A type boolean
     */
    public boolean getNSubmitDisabled() {
        return nSubmitDisabled;
    }

    /**
     * Set the private variable nSubmitDisabled
     *
     * @param nSubmitDisabled A type of boolean
     */
    public void setNSubmitDisabled(boolean nSubmitDisabled) {
        this.nSubmitDisabled = nSubmitDisabled;
    }
    
    /**
     * Retrieve the private variable mSubmitDisabled
     *
     * @return A type boolean
     */
    public boolean getMSubmitDisabled() {
        return mSubmitDisabled;
    }

    /**
     * Set the private variable mSubmitDisabled
     *
     * @param mSubmitDisabled A type of boolean
     */
    public void setMSubmitDisabled(boolean mSubmitDisabled) {
        this.mSubmitDisabled = mSubmitDisabled;
    }

     /**
     * Retrieve the private variable rawCode
     *
     * @return A type boolean
     */
    public boolean isRawCode() {
        return rawCode;
    }

    
    /**
     * Set the private variable rawCode
     *
     * @param rawCode A type of boolean
     */
    public void setRawCode(boolean rawCode) {
        this.rawCode = rawCode;
    }
    

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

    public Task getTask() {
        return task;
    }

    /**
     * Set the private variable task
     *
     * @param task A type of Task
     */
    public void setTask(Task task) {
        this.task = task;
    }
    
    public FileTask getFileTask() {
        return fileTask;
    }
    
    /**
     * Set the private variable codigo
     *
     * @param codigo A type of String
     */
    public void setCodigo(String codigo) {
        this.codigo = codigo;
    }
    
    public String getCodigo() {
        return codigo;
    }

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

    public InputStream getContentType() {
        return docInputStream;
    }

    /**
     * Set the private variable docInputStream
     *
     * @param docInputStream A type of InputStream
     */
    public void setContentType(InputStream docInputStream) {
        this.docInputStream = docInputStream;
    }
    
    /**
     * Set the private variable languaje
     *
     * @param languaje A type of Languaje
     */
    public void setLanguaje(Languaje languaje) {
        this.languaje = languaje;
    }
    
    public Languaje getLanguaje() {
        return languaje;
    }
 
    /**
     * Get a list of arguments selected
     *
     * @return List of ArgumentPreset
     */
    public List<ArgumentPreset> getSelectedPresets() {
        return selectedPresets;
    }

    /**
     * Set the private variable selectedPresets with the selected arguments.
     *
     * @param selectedPresets A List of ArgumentPreset
     */
    public void setSelectedPresets(List<ArgumentPreset> selectedPresets) {
        this.selectedPresets = selectedPresets;
    }
    
    /**
     * Set the private variable extraArguments
     *
     * @param extraArguments A string containing arguments
     */
    public void setExtraArguments(String extraArguments) {
        this.extraArguments = extraArguments;
    }
    
    public String getExtraArguments() {
        return extraArguments;
    }
    
    /**
     * Get the actual language extension
     *
     * @return String with the language file extension
     */
    public String getLanguageExtension() {
        return langExt;
    }
    
    /**
     * Get the list of uploaded files.
     * @return Uploaded files
     */
    public List<FileTask> getDocFiles() {
        return docFiles;
    }

    public void setDocFiles(List<FileTask> docFiles) {
        this.docFiles = docFiles;
    }
    
    public List<String> getMimeTypes() {
        return mimeTypes;
    }

    public void setMimeTypes(List<String> mimeTypes) {
        this.mimeTypes = mimeTypes;
    }

    public FileTask getMakefile() {
        return makefile;
    }
    
    public List<String> getSelectedTypes() {
        return selectedTypes;
    }

    public void setSelectedTypes(List<String> selectedTypes) {
        this.selectedTypes = selectedTypes;
    }
}
