package compiler;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

import utils.AyudaDebug;

/**
 * Clase encargada de la creación de comandas para ejecutarse en terminal de linux
 *
 * @author Enrique M.L
 *  
 */
public class Build {
    
	/**
	 * JAVA_BIN guarda el path del binario de ejecución de Java
	 */
	private static final String JAVA_BIN = "/usr/bin/java";
	/**
	 * PYTHON_BIN guarda el path del binario de ejecución de Python
	 */
	private static final String PYTHON_BIN = "/usr/bin/python";
 
    /**
     * Método que crea un comando para eliminar la carpeta con path 'filepath'
     * 
     * @param filepath
     * @return
     */
    public static ArrayList<String> buildDeleteFolderCommand(String filepath){
        
        AyudaDebug.printMetodo("buildDeleteFolderCommand:init");
        
        ArrayList<String> command = new ArrayList<String>();
        command.add("rm");
        command.add("-r");
        command.add("-f");
        command.add(filepath);
        
        AyudaDebug.printCommand(command);
        AyudaDebug.printMetodo("buildDeleteFolderCommand:end");
        
        return command;
    }
    
    /**
     * Método que crea un comando para eliminar el archivo con path 'filepath'
     * 
     * @param filepath
     * @return
     */
    public static ArrayList<String> buildDeleteFileCommand(String filepath){
        
        AyudaDebug.printMetodo("buildDeleteFileCommand:init");
        
        ArrayList<String> command = new ArrayList<String>();
        command.add("rm");
        command.add(filepath);
        
        AyudaDebug.printCommand(command);
        AyudaDebug.printMetodo("buildDeleteFileCommand:end");
        
        return command;
    }

    /**
     * Crea un comando para crear una carpeta con path 'nameFolder'
     * 
     * @param temp_file
     * @return
     */
    public static ArrayList<String> buildFolderCommand(String nameFolder) {
        
        AyudaDebug.printMetodo("buildFolderCommand:init");
        
        ArrayList<String> command = new ArrayList<String>();
        command.add("mkdir");
        command.add(nameFolder);
        
        AyudaDebug.printCommand(command);
        AyudaDebug.printMetodo("buildFolderCommand:end");
        
        return command;
    }

    
    /**
     * Método que crea un comando para compilar y crear el ejecutable del código contendio en el fichero 'nameFile' con extensión 'fileExtension'
     * mediante la instrucción de compilación 'compileIntruction'
     * 
     * @param nameFile
     * @param fileExtension
     * @param compileInstruction
     * @param arguments
     * @return
     */
    public static ArrayList<String> buildCompileToExecCommand(String nameFile, String fileExtension, String compileInstruction, String arguments) {
        
        AyudaDebug.printMetodo("buildCompileAndExecCommand:init");
        
        ArrayList<String> command = new ArrayList<String>();
        command.add(compileInstruction);
        
        if (!compileInstruction.equals("make")){
            if (".c".equals(fileExtension)){
                command.add("-o");
                command.add(nameFile);
            }
            command.add(nameFile + fileExtension);
        }
        
        if (!arguments.equals("")){
            //command.add("-L/opt/lib");
            command.addAll(Arrays.asList(arguments.split(" ")));
        }

        AyudaDebug.printCommand(command);
        AyudaDebug.printMetodo("buildCompileAndExecCommand:end");
        
        return command;
    }
    
    /**
     * Crea un comando para comprobar si existe el archivo con nombre 'find'
     * 
     * @param find
     * @return
     */
    public static ArrayList<String> buildExistCommand(String find) {
        
        AyudaDebug.printMetodo("buildExistCommand:init");
        
        ArrayList<String> command = new ArrayList<String>();
        command.add("find");
        command.add(".");
        command.add("-type");
        command.add("d");
        command.add("-name");
        command.add(find);

        AyudaDebug.printCommand(command);
        AyudaDebug.printMetodo("buildExistCommand:end");
        
        return command;
    }
        
    /**
     * Crea un comando para ejecutar el fichero 'nameFile' 
     * 
     * @param nameFile
     * @return 
     */
    public static ArrayList<String> buildRunCommand(String nameFile){
        
        AyudaDebug.printMetodo("buildRunCommand:init");
        
        ArrayList<String> command = new ArrayList<String>();
        command.add("./"+nameFile);
        
        AyudaDebug.printCommand(command);
        
        AyudaDebug.printMetodo("buildRunCommand:end");
        
        return command;
    }
    
    /**
     * Crea un comando que realiza la ejecución del programa 'nameFile' contenido en el directorio 'dirTask' con lenguaje 'language' dentro de nurse(sandbox)
     * <p>
     * El valor 0 o 1 que se añade como parametro a nurse(sandbox) indica si no se permiten llamadas a sistema(0), o si(1)
     * 
     * @param nameFile
     * @param dirTask
     * @param language
     * @return
     */
    public static ArrayList<String> buildRunNurseCommand(String nameFile, String dirTask, String fileExtension){
        
        AyudaDebug.printMetodo("buildRunNurseCommand:init");
        
        ArrayList<String> command = new ArrayList<String>();
        command.add("./src/sandbox");
        if (fileExtension.equals(".c")){
        	command.add("0");
        	command.add(dirTask+nameFile);
        }
        else if (fileExtension.equals(".java")){
        	command.add("1");
        	command.add(JAVA_BIN);
        	command.add("-cp");
        	command.add(dirTask);
                //policies
                command.add("-Djava.security.manager");
                command.add("-Djava.security.policy=./javaPolicies/JavaPerms.policy");
                //end/policies
        	command.add(nameFile);
        	
        }
        else if (fileExtension.equals(".py")){
        	command.add("1");
        	command.add(PYTHON_BIN);
        	command.add(dirTask+nameFile+fileExtension);
        } 
        
        AyudaDebug.printCommand(command);

        AyudaDebug.printMetodo("buildRunNurseCommand:end");
        
        return command;
    }
    
    /**
     * Crea un comando que realiza la ejecución del programa 'nombreFichero' contenido en el directorio 'dirTask' con lenguaje 'language'
     * con los argumentos 'arguments' dentro de nurse(sandbox)
     * @param nombreFichero
     * @param argumentos
     * @param dirTask
     * @param fileExtension
     * @return
     */
    public static ArrayList<String> buildRunNurseTestCommand(String nombreFichero, ArrayList<String> argumentos, String dirTask, String fileExtension) {
        AyudaDebug.printMetodo("buildRunNurseTestCommand:init");
        //Arguments of the test
        ArrayList<String> command = buildRunNurseCommand(nombreFichero, dirTask, fileExtension);
        
        Iterator<String> ite = argumentos.iterator();
        
        while (ite.hasNext()) {
            command.add(ite.next());
        }
        
        AyudaDebug.printCommand(command);
        
        AyudaDebug.printMetodo("buildRunNurseTestCommand:end");
        
        return command;
    }

    /**
     * Crea un command para ejecutar un programa 'nameFile' con los argumentos 'arguments'
     * Retorna el command necesario
     * 
     * @param nameFile
     * @param arguments
     * @return 
     */
    public static ArrayList<String> buildRunTestCommand(String nameFile, ArrayList<String> arguments) {
        AyudaDebug.printMetodo("buildRunTestCommand:init");
        //Arguments of the test
        ArrayList<String> command = new ArrayList<String>();
        command.add("./"+nameFile);
        
        Iterator<String> ite = arguments.iterator();
        
        while (ite.hasNext()) {
            command.add(ite.next());
        }
        
        AyudaDebug.printCommand(command);
        
        AyudaDebug.printMetodo("buildRunTestCommand:end");
        
        return command;
    }


    /**
     * Crea una comando para obtener la lista de nombres de elmentos contenidos en una carpeta 
     * @return
     */
    public static ArrayList<String> buildGetListFolderCommand() {
        
        AyudaDebug.printMetodo("buildGetListFolderCommand:init");
        ArrayList<String> command = new ArrayList<String>();
        command.add("ls");

        AyudaDebug.printCommand(command);
        AyudaDebug.printMetodo("buildGetListFolderCommand:end");
        
        return command;
    }
    
}


