/*
 * Copyright (C) 2010 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 com.android.cts.tradefed.testtype;

import com.android.cts.util.AbiUtils;
import com.android.ddmlib.Log.LogLevel;
import com.android.ddmlib.testrunner.TestIdentifier;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.targetprep.ITargetPreparer;
import com.android.tradefed.testtype.IAbi;
import com.android.tradefed.testtype.IRemoteTest;
import com.android.tradefed.testtype.InstrumentationTest;
import com.android.tradefed.util.StreamUtil;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Container for CTS test info.
 * <p/>
 * Knows how to translate this info into a runnable {@link IRemoteTest}.
 */
class TestPackageDef implements ITestPackageDef {

    public static final String HOST_SIDE_ONLY_TEST = "hostSideOnly";
    public static final String NATIVE_TEST = "native";
    public static final String WRAPPED_NATIVE_TEST = "wrappednative";
    public static final String VM_HOST_TEST = "vmHostTest";
    public static final String DEQP_TEST = "deqpTest";
    public static final String UIAUTOMATOR_TEST = "uiAutomator";
    public static final String JUNIT_DEVICE_TEST = "jUnitDeviceTest";

    private String mAppPackageName = null;
    private String mAppNameSpace = null;
    private String mName = null;
    private String mRunner = null;
    private String mTestType = null;
    private String mJarPath = null;
    private String mRunTimeArgs = null;
    private String mTestPackageName = null;
    private String mDigest = null;
    private IAbi mAbi = null;
    private List<ITargetPreparer> mPreparers = null;

    // use a LinkedHashSet for predictable iteration insertion-order, and fast
    // lookups
    private Collection<TestIdentifier> mTests = new LinkedHashSet<TestIdentifier>();
    // also maintain an index of known test classes
    private Collection<String> mTestClasses = new LinkedHashSet<String>();
    // store instance arguments in order too for consistency
    private Map<TestIdentifier, List<Map<String, String>>> mTestInstanceArguments =
            new LinkedHashMap<>();

    // dynamic options, not parsed from package xml
    private String mClassName;
    private String mMethodName;
    private TestFilter mTestFilter = new TestFilter();
    private String mTargetBinaryName;
    private String mTargetNameSpace;
    // only timeout per package is supported. To change this to method granularity,
    // test invocation should be done in method level.
    // So for now, only max timeout for the package is used.
    private int mTimeoutInMins = -1;

    @Override
    public IAbi getAbi() {
        return mAbi;
    }

    /**
     * @param abi the ABI to run this package on
     */
    public void setAbi(IAbi abi) {
        mAbi = abi;
    }

    /**
     * @return unique id representing this test package for this ABI.
     */
    @Override
    public String getId() {
        return AbiUtils.createId(getAbi().getName(), getAppPackageName());
    }

    void setAppPackageName(String appPackageName) {
        mAppPackageName = appPackageName;
    }

    String getAppPackageName() {
        return mAppPackageName;
    }

    void setRunTimeArgs(String runTimeArgs) {
        mRunTimeArgs = runTimeArgs;
    }

    void setAppNameSpace(String appNameSpace) {
        mAppNameSpace = appNameSpace;
    }

    String getAppNameSpace() {
        return mAppNameSpace;
    }

    void setName(String name) {
        mName = name;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getName() {
        return mName;
    }

    void setRunner(String runnerName) {
        mRunner = runnerName;
    }

    String getRunner() {
        return mRunner;
    }

    void setTestType(String testType) {
        mTestType = testType;
    }

    String getTestType() {
        return mTestType;
    }

    void setJarPath(String jarPath) {
        mJarPath = jarPath;
    }

    String getJarPath() {
        return mJarPath;
    }

    void setTestPackageName(String testPackageName) {
        mTestPackageName = testPackageName;
    }

    void setTargetBinaryName(String targetBinaryName) {
        mTargetBinaryName = targetBinaryName;
    }

    void setTargetNameSpace(String targetNameSpace) {
        mTargetNameSpace = targetNameSpace;
    }

    @Override
    public String getTargetApkName() {
       if (mTargetBinaryName != null && !mTargetBinaryName.isEmpty()) {
           return String.format("%s.apk", mTargetBinaryName);
       }
       return null;
    }

    @Override
    public String getTargetPackageName() {
        if (mTargetNameSpace != null && mTargetNameSpace.isEmpty()) {
            return null;
        }
        return mTargetNameSpace;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setTestFilter(TestFilter testFilter) {
        mTestFilter = testFilter;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setClassName(String className, String methodName) {
        mClassName = className;
        mMethodName = methodName;
    }

    /**
     * Setter for injecting a list of {@link ITargetPreparer}s as configured in module test config.
     * @param preparers
     */
    void setPackagePreparers(List<ITargetPreparer> preparers) {
        mPreparers = preparers;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<ITargetPreparer> getPackagePreparers() {
        return mPreparers;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IRemoteTest createTest(File testCaseDir) {
        mTestFilter.setTestInclusion(mClassName, mMethodName);
        mTests = filterTests();

        if (HOST_SIDE_ONLY_TEST.equals(mTestType)) {
            CLog.d("Creating host test for %s", mName);
            JarHostTest hostTest = new JarHostTest();
            if (mTimeoutInMins >= 0) {
                CLog.d("Setting new timeout to " + mTimeoutInMins + " mins");
                hostTest.setTimeout(mTimeoutInMins * 60 * 1000);
            }
            hostTest.setRunName(mAppPackageName);
            hostTest.setJarFileName(mJarPath);
            hostTest.setTests(mTests);
            hostTest.setAbi(mAbi);
            mDigest = generateDigest(testCaseDir, mJarPath);
            return hostTest;
        } else if (VM_HOST_TEST.equals(mTestType)) {
            CLog.d("Creating vm host test for %s", mName);
            VMHostTest vmHostTest = new VMHostTest();
            vmHostTest.setRunName(mAppPackageName);
            vmHostTest.setJarFileName(mJarPath);
            vmHostTest.setTests(mTests);
            vmHostTest.setAbi(mAbi);
            mDigest = generateDigest(testCaseDir, mJarPath);
            return vmHostTest;
        } else if (DEQP_TEST.equals(mTestType)) {
            DeqpTestRunner deqpTest =
                    new DeqpTestRunner(mAppPackageName, mName, mTests, mTestInstanceArguments);
            deqpTest.setAbi(mAbi);
            return deqpTest;
        } else if (NATIVE_TEST.equals(mTestType)) {
            GeeTest geeTest = new GeeTest(mAppPackageName, mName);
            geeTest.setAbi(mAbi);
            return geeTest;
        } else if (WRAPPED_NATIVE_TEST.equals(mTestType)) {
            CLog.d("Creating new wrapped native test for %s", mName);
            WrappedGTest wrappedGeeTest = new WrappedGTest(mAppNameSpace, mAppPackageName, mName, mRunner);
            wrappedGeeTest.setAbi(mAbi);
            return wrappedGeeTest;
        } else if (UIAUTOMATOR_TEST.equals(mTestType)) {
            UiAutomatorJarTest uiautomatorTest = new UiAutomatorJarTest();
            return setUiAutomatorTest(uiautomatorTest);
        } else if (JUNIT_DEVICE_TEST.equals(mTestType)){
            CLog.d("Creating JUnit device test %s", mName);
            JUnitDeviceTest jUnitDeviceTest = new JUnitDeviceTest();
            jUnitDeviceTest.setRunName(mAppPackageName);
            jUnitDeviceTest.addTestJarFileName(mJarPath);
            jUnitDeviceTest.addRunTimeArgs(mRunTimeArgs);
            jUnitDeviceTest.setTests(mTests);
            jUnitDeviceTest.setAbi(mAbi);
            mDigest = generateDigest(testCaseDir, mJarPath);
            return jUnitDeviceTest;
        } else {
            CLog.d("Creating instrumentation test for %s", mName);
            CtsInstrumentationApkTest instrTest = new CtsInstrumentationApkTest();
            if (mTimeoutInMins >= 0) {
                // as timeout cannot be set for each test,
                // increase the time-out of the whole package
                CLog.d("Setting new timeout to " + mTimeoutInMins + " mins");
                instrTest.setTestTimeout(mTimeoutInMins * 60 * 1000);
            }
            return setInstrumentationTest(instrTest, testCaseDir);
        }
    }

    /**
     * Populates given {@link CtsInstrumentationApkTest} with data from the package xml.
     *
     * @param testCaseDir
     * @param instrTest
     * @return the populated {@link InstrumentationTest} or <code>null</code>
     */
    private InstrumentationTest setInstrumentationTest(CtsInstrumentationApkTest instrTest,
            File testCaseDir) {
        instrTest.setRunName(mAppPackageName);
        instrTest.setPackageName(mAppNameSpace);
        instrTest.setRunnerName(mRunner);
        instrTest.setAbi(mAbi);
        instrTest.setTestsToRun(mTests, false
            /* force batch mode off to always run using testFile */);
        instrTest.setReRunUsingTestFile(true);
        // mName means 'apk file name' for instrumentation tests
        instrTest.addInstallApk(String.format("%s.apk", mName), mAppNameSpace);
        mDigest = generateDigest(testCaseDir, String.format("%s.apk", mName));
        if (mTests.size() > 1000) {
            // TODO: hack, large test suites can take longer to collect tests, increase timeout
            instrTest.setCollectsTestsShellTimeout(10 * 60 * 1000);
        }
        return instrTest;
    }

    /**
     * Populates given {@link UiAutomatorJarTest} with data from the package xml.
     *
     * @param uiautomatorTest
     * @return the populated {@link UiAutomatorJarTest} or <code>null</code>
     */
    @SuppressWarnings("deprecation")
    private IRemoteTest setUiAutomatorTest(UiAutomatorJarTest uiautomatorTest) {
        uiautomatorTest.setInstallArtifacts(getJarPath());
        if (mClassName != null) {
            if (mMethodName != null) {
                CLog.logAndDisplay(LogLevel.WARN, "ui automator tests don't currently support" +
                        "running  individual methods");
            }
            uiautomatorTest.addClassName(mClassName);
        } else {
            uiautomatorTest.addClassNames(mTestClasses);
        }
        uiautomatorTest.setRunName(mAppPackageName);
        uiautomatorTest.setCaptureLogs(false);
        return uiautomatorTest;
    }

    /**
     * Filter the tests to run based on list of included/excluded tests, class and method name.
     *
     * @return the filtered collection of tests
     */
    private Collection<TestIdentifier> filterTests() {
        mTestFilter.setTestInclusion(mClassName, mMethodName);
        return mTestFilter.filter(mTests);
    }

    boolean isKnownTestClass(String className) {
        return mTestClasses.contains(className);
    }

    /**
     * Add a {@link TestIdentifier} to the list of tests in this package.
     *
     * @param testDef
     * @param timeout in mins
     */
    void addTest(TestIdentifier testDef, int timeout) {
        mTests.add(testDef);
        mTestClasses.add(testDef.getClassName());
        mTestInstanceArguments.put(testDef, new LinkedList<Map<String, String>>());
        // 0 means no timeout, so keep 0 if already is.
        if ((timeout > mTimeoutInMins) && (mTimeoutInMins != 0)) {
            mTimeoutInMins = timeout;
        }
    }

    /**
     * Add a test instance to an existing {@link TestIdentifier}.
     */
    void addTestInstance(TestIdentifier testDef, Map<String, String> instanceArguments) {
        if (!mTestInstanceArguments.containsKey(testDef)) {
            throw new IllegalStateException("test id does not name an existing test");
        }
        mTestInstanceArguments.get(testDef).add(instanceArguments);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Collection<TestIdentifier> getTests() {
        return mTests;
    }

    /**
     * Get the instance argument map for tests.
     * <p/>
     * Exposed for unit testing.
     */
    public Map<TestIdentifier, List<Map<String, String>>> getTestInstanceArguments() {
        return mTestInstanceArguments;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getDigest() {
        return mDigest;
    }

    /**
     * Generate a sha1sum digest for a file.
     * <p/>
     * Exposed for unit testing.
     *
     * @param fileDir the directory of the file
     * @param fileName the name of the file
     * @return a hex {@link String} of the digest
     */
    String generateDigest(File fileDir, String fileName) {
        final String algorithm = "SHA-1";
        InputStream fileStream = null;
        DigestInputStream d = null;
        try {
            fileStream = getFileStream(fileDir, fileName);
            MessageDigest md = MessageDigest.getInstance(algorithm);
            d = new DigestInputStream(fileStream, md);
            byte[] buffer = new byte[8196];
            while (d.read(buffer) != -1) {
            }
            return toHexString(md.digest());
        } catch (NoSuchAlgorithmException e) {
            return algorithm + " not found";
        } catch (IOException e) {
            CLog.e(e);
        } finally {
            StreamUtil.close(d);
            StreamUtil.close(fileStream);
        }
        return "failed to generate digest";
    }

    /**
     * Retrieve an input stream for given file
     * <p/>
     * Exposed so unit tests can mock.
     */
    InputStream getFileStream(File fileDir, String fileName) throws FileNotFoundException {
        InputStream fileStream;
        fileStream = new BufferedInputStream(new FileInputStream(new File(fileDir, fileName)));
        return fileStream;
    }

    /**
     * Convert the given byte array into a lowercase hex string.
     *
     * @param arr The array to convert.
     * @return The hex encoded string.
     */
    private String toHexString(byte[] arr) {
        StringBuilder buf = new StringBuilder(arr.length * 2);
        for (byte b : arr) {
            buf.append(String.format("%02x", b & 0xFF));
        }
        return buf.toString();
    }

    @Override
    public int compareTo(ITestPackageDef testPackageDef) {
        return getId().compareTo(testPackageDef.getId());
    }
}
