/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package util.build;

import com.android.dx.util.FileUtils;

import dot.junit.AllTests;

import junit.framework.TestCase;
import junit.framework.TestResult;
import junit.framework.TestSuite;
import junit.textui.TestRunner;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Main class to generate data from the test suite to later run from a shell
 * script. the project's home folder.<br>
 * <project-home>/src must contain the java sources<br>
 * <project-home>/src/<for-each-package>/Main_testN1.java will be generated<br>
 * (one Main class for each test method in the Test_... class
 */
public class BuildDalvikSuite {

    public static boolean DEBUG = true;

    private static String JAVASRC_FOLDER = "";
    private static String MAIN_SRC_OUTPUT_FOLDER = "";

    // the folder for the generated junit-files for the cts host (which in turn
    // execute the real vm tests using adb push/shell etc)
    private static String HOSTJUNIT_SRC_OUTPUT_FOLDER = "";
    private static String OUTPUT_FOLDER = "";
    private static String COMPILED_CLASSES_FOLDER = "";

    private static String CLASSES_OUTPUT_FOLDER = "";
    private static String HOSTJUNIT_CLASSES_OUTPUT_FOLDER = "";

    private static String CLASS_PATH = "";

    private static String restrictTo = null; // e.g. restrict to "opcodes.add_double"

    private static final String TARGET_JAR_ROOT_PATH = "/data/local/tmp/vm-tests";

    private int testClassCnt = 0;
    private int testMethodsCnt = 0;

    /*
     * using a linked hashmap to keep the insertion order for iterators.
     * the junit suite/tests adding order is used to generate the order of the
     * report.
     * a map. key: fully qualified class name, value: a list of test methods for
     * the given class
     */
    private LinkedHashMap<String, List<String>> map = new LinkedHashMap<String,
    List<String>>();

    private class MethodData {
        String methodBody, constraint, title;
    }

    /**
     * @param args
     *            args 0 must be the project root folder (where src, lib etc.
     *            resides)
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {

        if (args.length > 5) {
            JAVASRC_FOLDER = args[0];
            OUTPUT_FOLDER = args[1];
            CLASS_PATH = args[2];
            MAIN_SRC_OUTPUT_FOLDER = args[3];
            CLASSES_OUTPUT_FOLDER = MAIN_SRC_OUTPUT_FOLDER + "/classes";

            COMPILED_CLASSES_FOLDER = args[4];

            HOSTJUNIT_SRC_OUTPUT_FOLDER = args[5];
            HOSTJUNIT_CLASSES_OUTPUT_FOLDER = HOSTJUNIT_SRC_OUTPUT_FOLDER + "/classes";

            if (args.length > 6) {
                // optional: restrict to e.g. "opcodes.add_double"
                restrictTo = args[6];
                System.out.println("restricting build to: " + restrictTo);
            }

        } else {
            System.out.println("usage: java-src-folder output-folder classpath " +
                    "generated-main-files compiled_output generated-main-files " +
            "[restrict-to-opcode]");
            System.exit(-1);
        }

        long start = System.currentTimeMillis();
        BuildDalvikSuite cat = new BuildDalvikSuite();
        cat.compose();
        long end = System.currentTimeMillis();

        System.out.println("elapsed seconds: " + (end - start) / 1000);
    }

    public void compose() throws IOException {
        System.out.println("Collecting all junit tests...");
        new TestRunner() {
            @Override
            protected TestResult createTestResult() {
                return new TestResult() {
                    @Override
                    protected void run(TestCase test) {
                        addToTests(test);
                    }

                };
            }
        }.doRun(AllTests.suite());

        // for each combination of TestClass and method, generate a Main_testN1
        // class in the respective package.
        // for the report make sure all N... tests are called first, then B,
        // then E, then VFE test methods.
        // e.g. dxc.junit.opcodes.aaload.Test_aaload - testN1() ->
        // File Main_testN1.java in package dxc.junit.opcodes.aaload.
        //
        handleTests();
    }

    private void addToTests(TestCase test) {

        String packageName = test.getClass().getPackage().getName();
        packageName = packageName.substring(packageName.lastIndexOf('.'));


        String method = test.getName(); // e.g. testVFE2
        String fqcn = test.getClass().getName(); // e.g.
        // dxc.junit.opcodes.iload_3.Test_iload_3

        // ignore all tests not belonging to the given restriction
        if (restrictTo != null && !fqcn.contains(restrictTo)) return;

        testMethodsCnt++;
        List<String> li = map.get(fqcn);
        if (li == null) {
            testClassCnt++;
            li = new ArrayList<String>();
            map.put(fqcn, li);
        }
        li.add(method);
    }
    private String curJunitFileName = null;
    private String curJunitFileData = "";

    private JavacBuildStep javacHostJunitBuildStep;

    private void flushHostJunitFile() {
        if (curJunitFileName != null) {
            File toWrite = new File(curJunitFileName);
            String absPath = toWrite.getAbsolutePath();
            // add to java source files for later compilation
            javacHostJunitBuildStep.addSourceFile(absPath);
            // write file
            curJunitFileData += "\n}\n";
            writeToFileMkdir(toWrite, curJunitFileData);
            curJunitFileName = null;
            curJunitFileData = "";
        }
    }

    private void openCTSHostFileFor(String pName, String classOnlyName) {
        // flush previous JunitFile
        flushHostJunitFile();
        String sourceName = "JUnit_" + classOnlyName;

        // prepare current testcase-file
        curJunitFileName = HOSTJUNIT_SRC_OUTPUT_FOLDER + "/" + pName.replaceAll("\\.","/") + "/" +
        sourceName + ".java";
        curJunitFileData = getWarningMessage() +
        "package " + pName + ";\n" +
        "import java.io.IOException;\n" +
        "import com.android.tradefed.testtype.DeviceTestCase;\n" +
        "\n" +
        "public class " + sourceName + " extends DeviceTestCase {\n";
    }

    private String getShellExecJavaLine(String classpath, String mainclass) {
      String cmd = String.format("ANDROID_DATA=%s dalvikvm -Xint:portable -Xmx512M -Xss32K " +
              "-Djava.io.tmpdir=%s -classpath %s %s", TARGET_JAR_ROOT_PATH, TARGET_JAR_ROOT_PATH,
              classpath, mainclass);
      return "String res = getDevice().executeShellCommand(\""+ cmd + "\");\n" +
             "// A sucessful adb shell command returns an empty string.\n" +
             "assertEquals(\"" + cmd + "\", \"\", res);";
    }

    private String getWarningMessage() {
        return "//Autogenerated code by " + this.getClass().getName() + "; do not edit.\n";
    }

    private void addCTSHostMethod(String pName, String method, MethodData md,
            Set<String> dependentTestClassNames) {
        curJunitFileData += "public void " + method + "() throws Exception {\n";
        final String targetCoreJarPath = String.format("%s/dot/junit/dexcore.jar",
                TARGET_JAR_ROOT_PATH);

        // push class with Main jar.
        String mjar = "Main_" + method + ".jar";
        String pPath = pName.replaceAll("\\.","/");
        String mainJar = String.format("%s/%s/%s", TARGET_JAR_ROOT_PATH, pPath, mjar);

        String cp = String.format("%s:%s", targetCoreJarPath, mainJar);
        for (String depFqcn : dependentTestClassNames) {
            int lastDotPos = depFqcn.lastIndexOf('.');
            String sourceName = depFqcn.replaceAll("\\.", "/") + ".jar";
            String targetName= String.format("%s/%s", TARGET_JAR_ROOT_PATH,
                    sourceName);
            cp += ":" + targetName;
            // dot.junit.opcodes.invoke_interface_range.ITest
            // -> dot/junit/opcodes/invoke_interface_range/ITest.jar
        }

        //"dot.junit.opcodes.add_double_2addr.Main_testN2";
        String mainclass = pName + ".Main_" + method;
        curJunitFileData += "    " + getShellExecJavaLine(cp, mainclass);
        curJunitFileData += "}\n\n";
    }

    private void handleTests() throws IOException {
        System.out.println("collected " + testMethodsCnt + " test methods in " +
                testClassCnt + " junit test classes");
        Set<BuildStep> targets = new TreeSet<BuildStep>();

        javacHostJunitBuildStep = new JavacBuildStep(HOSTJUNIT_CLASSES_OUTPUT_FOLDER, CLASS_PATH);


        JavacBuildStep javacBuildStep = new JavacBuildStep(
                CLASSES_OUTPUT_FOLDER, CLASS_PATH);

        for (Entry<String, List<String>> entry : map.entrySet()) {

            String fqcn = entry.getKey();
            int lastDotPos = fqcn.lastIndexOf('.');
            String pName = fqcn.substring(0, lastDotPos);
            String classOnlyName = fqcn.substring(lastDotPos + 1);
            String instPrefix = "new " + classOnlyName + "()";

            openCTSHostFileFor(pName, classOnlyName);

            List<String> methods = entry.getValue();
            Collections.sort(methods, new Comparator<String>() {
                public int compare(String s1, String s2) {
                    // TODO sort according: test ... N, B, E, VFE
                    return s1.compareTo(s2);
                }
            });
            for (String method : methods) {
                // e.g. testN1
                if (!method.startsWith("test")) {
                    throw new RuntimeException("no test method: " + method);
                }

                // generate the Main_xx java class

                // a Main_testXXX.java contains:
                // package <packagenamehere>;
                // public class Main_testxxx {
                // public static void main(String[] args) {
                // new dxc.junit.opcodes.aaload.Test_aaload().testN1();
                // }
                // }
                MethodData md = parseTestMethod(pName, classOnlyName, method);
                String methodContent = md.methodBody;

                Set<String> dependentTestClassNames = parseTestClassName(pName,
                        classOnlyName, methodContent);

                addCTSHostMethod(pName, method, md, dependentTestClassNames);


                if (dependentTestClassNames.isEmpty()) {
                    continue;
                }


                String content = getWarningMessage() +
                "package " + pName + ";\n" +
                "import " + pName + ".d.*;\n" +
                "import dot.junit.*;\n" +
                "public class Main_" + method + " extends DxAbstractMain {\n" +
                "    public static void main(String[] args) throws Exception {" +
                methodContent + "\n}\n";

                String fileName = getFileName(pName, method, ".java");
                File sourceFile = getFileFromPackage(pName, method);

                File classFile = new File(CLASSES_OUTPUT_FOLDER + "/" +
                        getFileName(pName, method, ".class"));
                // if (sourceFile.lastModified() > classFile.lastModified()) {
                writeToFile(sourceFile, content);
                javacBuildStep.addSourceFile(sourceFile.getAbsolutePath());

                BuildStep dexBuildStep = generateDexBuildStep(
                        CLASSES_OUTPUT_FOLDER, getFileName(pName, method, ""));
                targets.add(dexBuildStep);
                // }

                generateBuildStepFor(pName, method, dependentTestClassNames,
                        targets);
            }


        }

        // write latest HOSTJUNIT generated file.
        flushHostJunitFile();

        if (!javacHostJunitBuildStep.build()) {
            System.out.println("main javac cts-host-hostjunit-classes build step failed");
            System.exit(1);
        }

        if (javacBuildStep.build()) {
            for (BuildStep buildStep : targets) {
                if (!buildStep.build()) {
                    System.out.println("building failed. buildStep: " +
                            buildStep.getClass().getName() + ", " + buildStep);
                    System.exit(1);
                }
            }
        } else {
            System.out.println("main javac dalvik-cts-buildutil build step failed");
            System.exit(1);
        }
    }

    private void generateBuildStepFor(String pName, String method,
            Set<String> dependentTestClassNames, Set<BuildStep> targets) {


        for (String dependentTestClassName : dependentTestClassNames) {
            generateBuildStepForDependant(dependentTestClassName, targets);
        }
    }

    private void generateBuildStepForDependant(String dependentTestClassName,
            Set<BuildStep> targets) {

        File sourceFolder = new File(JAVASRC_FOLDER);
        String fileName = dependentTestClassName.replace('.', '/').trim();

        if (new File(sourceFolder, fileName + ".dfh").exists()) {

            BuildStep.BuildFile inputFile = new BuildStep.BuildFile(
                    JAVASRC_FOLDER, fileName + ".dfh");
            BuildStep.BuildFile dexFile = new BuildStep.BuildFile(
                    OUTPUT_FOLDER, fileName + ".dex");

            DFHBuildStep buildStep = new DFHBuildStep(inputFile, dexFile);

            BuildStep.BuildFile jarFile = new BuildStep.BuildFile(
                    OUTPUT_FOLDER, fileName + ".jar");
            JarBuildStep jarBuildStep = new JarBuildStep(dexFile,
                    "classes.dex", jarFile, true);
            jarBuildStep.addChild(buildStep);

            targets.add(jarBuildStep);
            return;
        }

        if (new File(sourceFolder, fileName + ".d").exists()) {

            BuildStep.BuildFile inputFile = new BuildStep.BuildFile(
                    JAVASRC_FOLDER, fileName + ".d");
            BuildStep.BuildFile dexFile = new BuildStep.BuildFile(
                    OUTPUT_FOLDER, fileName + ".dex");

            DasmBuildStep buildStep = new DasmBuildStep(inputFile, dexFile);

            BuildStep.BuildFile jarFile = new BuildStep.BuildFile(
                    OUTPUT_FOLDER, fileName + ".jar");

            JarBuildStep jarBuildStep = new JarBuildStep(dexFile,
                    "classes.dex", jarFile, true);
            jarBuildStep.addChild(buildStep);
            targets.add(jarBuildStep);
            return;
        }

        if (new File(sourceFolder, fileName + ".java").exists()) {

            BuildStep dexBuildStep = generateDexBuildStep(
                    COMPILED_CLASSES_FOLDER, fileName);
            targets.add(dexBuildStep);
            return;
        }

        try {
            if (Class.forName(dependentTestClassName) != null) {

                BuildStep dexBuildStep = generateDexBuildStep(
                        COMPILED_CLASSES_FOLDER, fileName);
                targets.add(dexBuildStep);
                return;
            }
        } catch (ClassNotFoundException e) {
            // do nothing
        }

        throw new RuntimeException("neither .dfh,.d,.java file of dependant test class found : " +
                dependentTestClassName + ";" + fileName);
    }

    private BuildStep generateDexBuildStep(String classFileFolder,
            String classFileName) {
        BuildStep.BuildFile classFile = new BuildStep.BuildFile(
                classFileFolder, classFileName + ".class");

        BuildStep.BuildFile tmpJarFile = new BuildStep.BuildFile(OUTPUT_FOLDER,
                classFileName + "_tmp.jar");

        JarBuildStep jarBuildStep = new JarBuildStep(classFile, classFileName +
                ".class", tmpJarFile, false);

        BuildStep.BuildFile outputFile = new BuildStep.BuildFile(OUTPUT_FOLDER,
                classFileName + ".jar");

        DexBuildStep dexBuildStep = new DexBuildStep(tmpJarFile, outputFile,
                true);

        dexBuildStep.addChild(jarBuildStep);
        return dexBuildStep;

    }

    /**
     * @param pName
     * @param classOnlyName
     * @param methodSource
     * @return testclass names
     */
    private Set<String> parseTestClassName(String pName, String classOnlyName,
            String methodSource) {
        Set<String> entries = new HashSet<String>();
        String opcodeName = classOnlyName.substring(5);

        Scanner scanner = new Scanner(methodSource);

        String[] patterns = new String[] {"new\\s(T_" + opcodeName + "\\w*)",
                "(T_" + opcodeName + "\\w*)", "new\\s(T\\w*)"};

        String token = null;
        for (String pattern : patterns) {
            token = scanner.findWithinHorizon(pattern, methodSource.length());
            if (token != null) {
                break;
            }
        }

        if (token == null) {
            System.err.println("warning: failed to find dependent test class name: " + pName +
                    ", " + classOnlyName + " in methodSource:\n" + methodSource);
            return entries;
        }

        MatchResult result = scanner.match();

        entries.add((pName + ".d." + result.group(1)).trim());

        // search additional @uses directives
        Pattern p = Pattern.compile("@uses\\s+(.*)\\s+", Pattern.MULTILINE);
        Matcher m = p.matcher(methodSource);
        while (m.find()) {
            String res = m.group(1);
            entries.add(res.trim());
        }

        // lines with the form @uses
        // dot.junit.opcodes.add_double.jm.T_add_double_2
        // one dependency per one @uses
        // TODO

        return entries;
    }

    private MethodData parseTestMethod(String pname, String classOnlyName,
            String method) {

        String path = pname.replaceAll("\\.", "/");
        String absPath = JAVASRC_FOLDER + "/" + path + "/" + classOnlyName + ".java";
        File f = new File(absPath);

        Scanner scanner;
        try {
            scanner = new Scanner(f);
        } catch (FileNotFoundException e) {
            throw new RuntimeException("error while reading to file: " + e.getClass().getName() +
                    ", msg:" + e.getMessage());
        }

        String methodPattern = "public\\s+void\\s+" + method + "[^\\{]+\\{";

        String token = scanner.findWithinHorizon(methodPattern, (int) f.length());
        if (token == null) {
            throw new RuntimeException("cannot find method source of 'public void " + method +
                    "' in file '" + absPath + "'");
        }

        MatchResult result = scanner.match();
        result.start();
        result.end();

        StringBuilder builder = new StringBuilder();
        //builder.append(token);

        try {
            FileReader reader = new FileReader(f);
            reader.skip(result.end());

            char currentChar;
            int blocks = 1;
            while ((currentChar = (char) reader.read()) != -1 && blocks > 0) {
                switch (currentChar) {
                    case '}': {
                        blocks--;
                        builder.append(currentChar);
                        break;
                    }
                    case '{': {
                        blocks++;
                        builder.append(currentChar);
                        break;
                    }
                    default: {
                        builder.append(currentChar);
                        break;
                    }
                }
            }
            if (reader != null) {
                reader.close();
            }
        } catch (Exception e) {
            throw new RuntimeException("failed to parse", e);
        }

        // find the @title/@constraint in javadoc comment for this method
        Scanner scanner2;
        try {
            // using platform's default charset
            scanner2 = new Scanner(f);
        } catch (FileNotFoundException e) {
            throw new RuntimeException("error while reading to file: " + e.getClass().getName() +
                    ", msg:" + e.getMessage());
        }
        // using platform's default charset
        String all = new String(FileUtils.readFile(f));
        // System.out.println("grepping javadoc found for method " + method +
        // " in " + pname + "," + classOnlyName);
        String commentPattern = "/\\*\\*([^{]*)\\*/\\s*" + methodPattern;
        Pattern p = Pattern.compile(commentPattern, Pattern.DOTALL);
        Matcher m = p.matcher(all);
        String title = null, constraint = null;
        if (m.find()) {
            String res = m.group(1);
            // System.out.println("res: " + res);
            // now grep @title and @constraint
            Matcher titleM = Pattern.compile("@title (.*)", Pattern.DOTALL)
            .matcher(res);
            if (titleM.find()) {
                title = titleM.group(1).replaceAll("\\n     \\*", "");
                title = title.replaceAll("\\n", " ");
                title = title.trim();
                // System.out.println("title: " + title);
            } else {
                System.err.println("warning: no @title found for method " + method + " in " + pname +
                        "," + classOnlyName);
            }
            // constraint can be one line only
            Matcher constraintM = Pattern.compile("@constraint (.*)").matcher(
                    res);
            if (constraintM.find()) {
                constraint = constraintM.group(1);
                constraint = constraint.trim();
                // System.out.println("constraint: " + constraint);
            } else if (method.contains("VFE")) {
                System.err
                .println("warning: no @constraint for for a VFE method:" + method + " in " +
                        pname + "," + classOnlyName);
            }
        } else {
            System.err.println("warning: no javadoc found for method " + method + " in " + pname +
                    "," + classOnlyName);
        }
        MethodData md = new MethodData();
        md.methodBody = builder.toString();
        md.constraint = constraint;
        md.title = title;
        if (scanner != null) {
            scanner.close();
        }
        if (scanner2 != null) {
            scanner2.close();
        }
        return md;
    }

    private void writeToFileMkdir(File file, String content) {
        File parent = file.getParentFile();
        if (!parent.exists() && !parent.mkdirs()) {
            throw new RuntimeException("failed to create directory: " + parent.getAbsolutePath());
        }
        writeToFile(file, content);
    }

    private void writeToFile(File file, String content) {
        try {
            if (file.length() == content.length()) {
                FileReader reader = new FileReader(file);
                char[] charContents = new char[(int) file.length()];
                reader.read(charContents);
                reader.close();
                String contents = new String(charContents);
                if (contents.equals(content)) {
                    // System.out.println("skipping identical: "
                    // + file.getAbsolutePath());
                    return;
                }
            }

            //System.out.println("writing file " + file.getAbsolutePath());

            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(file), "utf-8"));
            bw.write(content);
            bw.close();
        } catch (Exception e) {
            throw new RuntimeException("error while writing to file: " + e.getClass().getName() +
                    ", msg:" + e.getMessage());
        }
    }

    private File getFileFromPackage(String pname, String methodName)
    throws IOException {
        // e.g. dxc.junit.argsreturns.pargsreturn
        String path = getFileName(pname, methodName, ".java");
        String absPath = MAIN_SRC_OUTPUT_FOLDER + "/" + path;
        File dirPath = new File(absPath);
        File parent = dirPath.getParentFile();
        if (!parent.exists() && !parent.mkdirs()) {
            throw new IOException("failed to create directory: " + absPath);
        }
        return dirPath;
    }

    private String getFileName(String pname, String methodName,
            String extension) {
        String path = pname.replaceAll("\\.", "/");
        return new File(path, "Main_" + methodName + extension).getPath();
    }
}
