import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Map;
import java.util.Hashtable;
import java.util.List;
import java.util.LinkedList;
import codeassess.javassessment.Assessor;
import codeassess.misc.Misc;

public class Template extends Assessor {

    public Map<String, String> getConfig() {
        final Map<String, String> config = new Hashtable<String, String>();
        config.put("Language", "Java");
        config.put("Extensions", ".java");
        config.put("AssessmentMode", "SemiAutomatic");
        return config;
    }

    public List<Object[]> getProperties() {
        final List<Object[]> properties = new LinkedList<Object[]>();
        properties.add(new Object[] { "Eval2", "Functionality", null, new String[] {  }, "GrupoFiguras.java", "Genericidad", "Genericidad", 3.0 });
        properties.add(new Object[] { "Eval12", "Functionality", "Eval2", new String[] {  }, "GrupoFiguras.java", "No debes modificar los parámetros genéricos de la clase", "Solo debe haber un parametro genérico en la clase GrupoFiguras", 0.0 });
        properties.add(new Object[] { "Eval3", "Functionality", "Eval2", new String[] { "Eval12" }, "GrupoFiguras.java", "Comprueba el tipo y nombre del atributo genérico", "GrupoFiguras debe tener un atributo genérico", 1.5 });
        properties.add(new Object[] { "Eval1", "Functionality", "Eval2", new String[] { "Eval12", "Eval3" }, "GrupoFiguras.java", "Comprueba el parámetro genérico", "El constructor de GrupoFiguras está bien implementado", 1.5 });
        properties.add(new Object[] { "Eval4", "Functionality", null, new String[] {  }, "Volumen.java", "Volumen", "Método desplazar", 7.0 });
        properties.add(new Object[] { "Eval5", "Functionality", "Eval4", new String[] {  }, "Volumen.java", "Comprueba nombre, tipo y parámetros del método", "Crear método \"desplazar\" en la interfaz Volumen", 1.0 });
        properties.add(new Object[] { "Eval6", "Functionality", "Eval4", new String[] {  }, "Cilindro.java", "Comprueba que has usado \"implements\"", "La clase Cilindro implementa la interfaz Volumen", 1.5 });
        properties.add(new Object[] { "Eval7", "Functionality", "Eval4", new String[] { "Eval5", "Eval6" }, "Cilindro.java", "Comprueba el tipo devuelto y los argumentos", "Crear método \"desplazar\" en la clase Cilindro", 1.5 });
        properties.add(new Object[] { "Eval8", "Functionality", "Eval4", new String[] {  }, "GrupoFiguras.java", "Comprueba el tipo devuelto y los parámetros", "Crear método \"desplazar\" en la clase GrupoFiguras", 3.0 });
        properties.add(new Object[] { "Eval11", "Functionality", "Eval8", new String[] {  }, "GrupoFiguras.java", "Comprueba los parámetros y tipo devuelto del método \"desplazar\"", "La clase GrupoFiguras implementa el método \"desplazar\"", 0.0 });
        properties.add(new Object[] { "Eval9", "Functionality", "Eval8", new String[] { "Eval11" }, "GrupoFiguras.java", "Comprueba los índices del bucle", "Se utiliza un bucle para recorrer todas las figuras", 1.5 });
        properties.add(new Object[] { "Eval13", "Functionality", "Eval8", new String[] { "Eval5" }, "Cubo.java", "Propiedad interna de ASys", "Adaptación del caso de test", 0.0 });
        properties.add(new Object[] { "Eval10", "Functionality", "Eval8", new String[] { "Eval11", "Eval9", "Eval13" }, "GrupoFiguras.java", "Utiliza \"instanceof\"", "Solo se desplazan figuras con volumen", 1.5 });
        return properties;
    }

    public boolean checkEval2() {
        return true;
    }

    public boolean solveEval2() {
        return false;
    }

    public String[] testEval2() {
        return null;
    }

    public boolean checkEval12() {
        final Class class1 = super.introspector.getClass("GrupoFiguras");
        if (class1 == null) return false;
        if (!(super.introspector.getGenericTypeParameterCount(class1) == 1)) return false;
        boolean typeVariable1Checker = false;
        for (TypeVariable typeVariable1 : super.introspector.getGenericTypeParameters(class1)) {
            typeVariable1Checker = true;
            break;
        }
        if (typeVariable1Checker == false) return false;
        return true;
    }

    public boolean solveEval12() {
        return false;
    }

    public String[] testEval12() {
        return null;
    }

    public boolean checkEval3() {
        final Class class1 = super.introspector.getClass("GrupoFiguras");
        if (class1 == null) return false;
        final Field field1 = super.introspector.getDeclaredField(class1, "favorita");
        if (field1 == null) return false;
        if (!(super.introspector.checkGenericType(field1) == true)) return false;
        return true;
    }

    public boolean solveEval3() {
        final Class class1 = super.introspector.getClass("GrupoFiguras");
        if (class1 == null) return false;
        boolean typeVariable1Checker = false;
        for (TypeVariable typeVariable1 : super.introspector.getGenericTypeParameters(class1)) {
            super.intercessor.copyField(class1, "favorita");
            typeVariable1Checker = true;
            break;
        }
        if (typeVariable1Checker == false) return false;
        return true;
    }

    public String[] testEval3() {
        return null;
    }

    public boolean checkEval1() {
        final Class class1 = super.introspector.getClass("GrupoFiguras");
        if (class1 == null) return false;
        boolean constructor1Checker = false;
        for (Constructor constructor1 : super.introspector.getDeclaredConstructors(class1)) {
            if (!(super.introspector.getParameterCount(constructor1) == 1)) continue;
            boolean typeVariable1Checker = false;
            for (TypeVariable typeVariable1 : super.introspector.getGenericTypeParameters(class1)) {
                boolean parameter1Checker = false;
                for (Parameter parameter1 : super.introspector.getParameters(constructor1)) {
                    if (!(super.introspector.checkGenericType(parameter1, typeVariable1) == true)) continue;
                    parameter1Checker = true;
                    break;
                }
                if (parameter1Checker == false) continue;
                typeVariable1Checker = true;
                break;
            }
            if (typeVariable1Checker == false) continue;
            constructor1Checker = true;
            break;
        }
        if (constructor1Checker == false) return false;
        return true;
    }

    public boolean solveEval1() {
        final Class class1 = super.introspector.getClass("GrupoFiguras");
        if (class1 == null) return false;
        super.intercessor.removeConstructors(class1);
        super.intercessor.copyConstructors(class1);
        return true;
    }

    public String[] testEval1() {
        return null;
    }

    public boolean checkEval4() {
        return true;
    }

    public boolean solveEval4() {
        return false;
    }

    public String[] testEval4() {
        return null;
    }

    public boolean checkEval5() {
        final Class class1 = super.introspector.getClass("Volumen");
        if (class1 == null) return false;
        if (!(super.introspector.isInterface(class1) == true)) return false;
        if (!(super.introspector.getDeclaredMethodCount(class1) == 2)) return false;
        final Class[] classs1 = { double.class, double.class };
        final Method method1 = super.introspector.getDeclaredMethod(class1, "desplazar", classs1, void.class, true);
        if (method1 == null) return false;
        return true;
    }

    public boolean solveEval5() {
        final Class class1 = super.introspector.getClass("Volumen");
        if (class1 == null) return false;
        super.intercessor.removeMethods(class1);
        super.intercessor.copyMethods(class1);
        return true;
    }

    public String[] testEval5() {
        return null;
    }

    public boolean checkEval6() {
        final Class class1 = super.introspector.getClass("Cilindro");
        if (class1 == null) return false;
        final Class class2 = super.introspector.getClass("Volumen");
        if (class2 == null) return false;
        if (!(super.introspector.isInterface(class2) == true)) return false;
        if (!(super.introspector.checkImplements(class1, class2) == true)) return false;
        return true;
    }

    public boolean solveEval6() {
        final Class class1 = super.introspector.getClass("Ciclindro");
        if (class1 == null) return false;
        final Class class2 = super.introspector.getClass("Volumen");
        if (class2 == null) return false;
        super.intercessor.addImplement(class1, class2);
        return true;
    }

    public String[] testEval6() {
        return null;
    }

    public boolean checkEval7() {
        final Class class1 = super.introspector.getClass("Cilindro");
        if (class1 == null) return false;
        final Class[] classs1 = { double.class, double.class };
        final Method method1 = super.introspector.getDeclaredMethod(class1, "desplazar", classs1, void.class, true);
        if (method1 == null) return false;
        return true;
    }

    public boolean solveEval7() {
        final Class class1 = super.introspector.getClass("Cilindro");
        if (class1 == null) return false;
        final Class[] classs1 = { double.class, double.class };
        super.intercessor.copyMethod(class1, "desplazar", classs1);
        return true;
    }

    public String[] testEval7() {
        if (!(super.tester.executeTestCase("TestCases", "test01").equals(true))) return new String[] { "TestCases", "test01" };
        return null;
    }

    public boolean checkEval8() {
        return true;
    }

    public boolean solveEval8() {
        return false;
    }

    public String[] testEval8() {
        return null;
    }

    public boolean checkEval11() {
        final Class class1 = super.introspector.getClass("GrupoFiguras");
        if (class1 == null) return false;
        final Class[] classs1 = { double.class, double.class };
        final Method method1 = super.introspector.getDeclaredMethod(class1, "desplazar", classs1, void.class, true);
        if (method1 == null) return false;
        return true;
    }

    public boolean solveEval11() {
        return false;
    }

    public String[] testEval11() {
        return null;
    }

    public boolean checkEval9() {
        return true;
    }

    public boolean solveEval9() {
        return false;
    }

    public String[] testEval9() {
        if (!(super.tester.executeTestCase("TestCases", "test02").equals(true))) return new String[] { "TestCases", "test02" };
        return null;
    }

    public boolean checkEval13() {
        final Class class1 = super.introspector.getClass("Cubo");
        if (class1 == null) return false;
        final Class class2 = super.introspector.getClass("Volumen");
        if (class2 == null) return false;
        if (!(super.introspector.checkImplements(class1, class2) == true)) return false;
        return true;
    }

    public boolean solveEval13() {
        final Class class1 = super.introspector.getClass("Cubo");
        if (class1 == null) return false;
        final Class class2 = super.introspector.getClass("Volumen");
        if (class2 == null) return false;
        super.intercessor.addImplement(class1, class2);
        return true;
    }

    public String[] testEval13() {
        return null;
    }

    public boolean checkEval10() {
        return true;
    }

    public boolean solveEval10() {
        return false;
    }

    public String[] testEval10() {
        if (!(super.tester.executeTestCase("TestCases", "test03").equals(true))) return new String[] { "TestCases", "test03" };
        return null;
    }
}
