/*
 * Copyright (C) 2009 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 dalvik.jtreg;

import com.sun.javatest.TestDescription;
import com.sun.javatest.TestResult;
import com.sun.javatest.TestResultTable;
import com.sun.javatest.TestSuite;
import com.sun.javatest.WorkDirectory;
import com.sun.javatest.regtest.RegressionTestSuite;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
import java.util.regex.Pattern;

/**
 * Scans a directory of jtreg tests and creates Dalvik-friendly {@code .jar}
 * files for them. These tests can be executed by {@link TestRunner}. Because of
 * the heavy use of the default package by jtreg tests, it is not generally
 * possible to run multiple tests in the same dalvik VM.
 */
final class TestToDex {

    private static final String DALVIK_JTREG_HOME
            = "dalvik/libcore/tools/dalvik_jtreg";
    private static final File JTREG_JAR
            = new File(DALVIK_JTREG_HOME + "/lib/jtreg.jar");
    private static final File TEST_RUNNER_JAVA
            = new File(DALVIK_JTREG_HOME + "/java/dalvik/jtreg/TestRunner.java");

    private static final Logger logger = Logger.getLogger(TestToDex.class.getName());

    private final Pattern JAVA_TEST_PATTERN = Pattern.compile("\\/(\\w)+\\.java$");

    private final File sdkJar;
    private final File temp;

    TestToDex(File sdkJar, File temp) {
        this.sdkJar = sdkJar;
        this.temp = temp;
    }

    /**
     * Creates a testrunner jar that can execute the packaged tests.
     */
    File writeTestRunnerJar() {
        File base = new File(temp, "testrunner");
        base.mkdirs();

        new Javac()
                .destination(base)
                .compile(TEST_RUNNER_JAVA);

        File output = new File(temp, "testrunner.jar");
        new Dx().dex(output.toString(), base);
        return output;
    }

    /**
     * Writes a Dalvik-friendly {@code .jar} for the described test.
     *
     * @return the path of the constructed {@code .jar}, or {@code null} if the
     *      test cannot be converted to Dex (presumably because it is not of
     *      the right type).
     * @throws CommandFailedException if javac fails
     */
    File dexify(TestDescription testDescription) throws IOException {
        String qualifiedName = TestDescriptions.qualifiedName(testDescription);

        if (!JAVA_TEST_PATTERN.matcher(testDescription.getFile().toString()).find()) {
            return null;
        }

        File jarContents = new File(temp, qualifiedName);
        jarContents.mkdirs();

        // write a test descriptor
        Properties properties = TestDescriptions.toProperties(testDescription);
        FileOutputStream propertiesOut = new FileOutputStream(
                new File(jarContents, TestRunner.TEST_PROPERTIES_FILE));
        properties.store(propertiesOut, "generated by " + getClass().getName());
        propertiesOut.close();

        new Javac()
                .bootClasspath(sdkJar)
                .classpath(testDescription.getDir(), JTREG_JAR)
                .sourcepath(testDescription.getDir())
                .destination(jarContents)
                .compile(testDescription.getFile());

        File output = new File(temp, qualifiedName + ".jar");
        new Dx().dex(output.toString(), jarContents);
        return output;
    }

    /**
     * Scans {@code directoryToScan} for test cases, using JTHarness + jtreg
     * behind the scenes.
     */
    List<TestDescription> findTests(File directoryToScan) throws Exception {
        logger.info("Scanning " + directoryToScan + " for tests.");
        File workDirectory = new File(temp, "JTwork");
        workDirectory.mkdirs();

        /*
         * This code is capable of extracting test descriptions using jtreg 4.0
         * and its bundled copy of jtharness. As a command line tool, jtreg's
         * API wasn't intended for this style of use. As a consequence, this
         * code is fragile and may be incompatible with newer versions of jtreg.
         */
        TestSuite testSuite = new RegressionTestSuite(directoryToScan);
        WorkDirectory wd = WorkDirectory.convert(workDirectory, testSuite);
        TestResultTable resultTable = wd.getTestResultTable();

        List<TestDescription> result = new ArrayList<TestDescription>();
        for (Iterator i = resultTable.getIterator(); i.hasNext(); ) {
            TestResult testResult = (TestResult) i.next();
            result.add(testResult.getDescription());
        }
        logger.info("Found " + result.size() + " tests.");
        return result;
    }
}
