/*
 * 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 libcore.dalvik.system;

import java.lang.reflect.Method;
import java.io.File;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;

import libcore.io.Streams;
import junit.framework.TestCase;

import dalvik.system.DexClassLoader;

/**
 * Tests for the class {@link DexClassLoader}.
 */
public class DexClassLoaderTest extends TestCase {

    private File dex1;
    private File dex2;
    private File jar1;
    private File jar2;
    private File nativeLib1;

    private Map<String, File> resourcesMap;

    protected void setUp() throws Exception {
        resourcesMap = ClassLoaderTestSupport.setupAndCopyResources(Arrays.asList(
                "loading-test.dex", "loading-test2.dex", "loading-test.jar", "loading-test2.jar",
                "libfake.so"));

        dex1 = resourcesMap.get("loading-test.dex");
        assertNotNull(dex1);
        dex2 = resourcesMap.get("loading-test2.dex");
        assertNotNull(dex2);
        jar1 = resourcesMap.get("loading-test.jar");
        assertNotNull(jar1);
        jar2 = resourcesMap.get("loading-test2.jar");
        assertNotNull(jar2);
        nativeLib1 = resourcesMap.get("libfake.so");
        assertNotNull(nativeLib1);
    }

    protected void tearDown() {
        ClassLoaderTestSupport.cleanUpResources(resourcesMap);
    }

    /**
     * Helper to construct a DexClassLoader instance to test.
     *
     * @param files The .dex or .jar files to use for the class path.
     */
    private ClassLoader createLoader(File... files) {
        assertNotNull(files);
        assertTrue(files.length > 0);
        String path = files[0].getAbsolutePath();
        for (int i = 1; i < files.length; i++) {
            path += File.pathSeparator + files[i].getAbsolutePath();
        }
        return new DexClassLoader(path, null, null,
            ClassLoader.getSystemClassLoader());
    }

    /**
     * Helper to construct a new DexClassLoader instance to test, using the
     * given files as the class path, and call a named no-argument static
     * method on a named class.
     *
     * @param className The name of the class of the method to call.
     * @param methodName The name of the method to call.
     * @param files The .dex or .jar files to use for the class path.
     */
    public Object createLoaderAndCallMethod(
            String className, String methodName, File... files)
            throws ReflectiveOperationException {
        ClassLoader cl = createLoader(files);
        Class c = cl.loadClass(className);
        Method m = c.getMethod(methodName, (Class[]) null);
        return m.invoke(null, (Object[]) null);
    }

    /**
     * Helper to construct a new DexClassLoader instance to test, using the
     * given files as the class path, and read the contents of the named
     * resource as a String.
     *
     * @param resourceName The name of the resource to get.
     * @param files The .dex or .jar files to use for the class path.
     */
    private String createLoaderAndGetResource(String resourceName, File... files) throws Exception {
        ClassLoader cl = createLoader(files);
        InputStream in = cl.getResourceAsStream(resourceName);
        if (in == null) {
            throw new IllegalStateException("Resource not found: " + resourceName);
        }

        byte[] contents = Streams.readFully(in);
        return new String(contents, "UTF-8");
    }

    // ONE_JAR

    /**
     * Just a trivial test of construction. This one merely makes
     * sure that a valid construction doesn't fail. It doesn't try
     * to verify anything about the constructed instance, other than
     * checking for the existence of optimized dex files.
     */
    public void test_oneJar_init() throws Exception {
        ClassLoader cl = createLoader(jar1);
    }

    /**
     * Check that a class in the jar/dex file may be used successfully. In this
     * case, a trivial static method is called.
     */
    public void test_oneJar_simpleUse() throws Exception {
        String result = (String) createLoaderAndCallMethod("test.Test1", "test", jar1);
        assertSame("blort", result);
    }

    /*
     * All the following tests are just pass-throughs to test code
     * that lives inside the loading-test dex/jar file.
     */

    public void test_oneJar_constructor() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_constructor", jar1);
    }

    public void test_oneJar_callStaticMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_callStaticMethod", jar1);
    }

    public void test_oneJar_getStaticVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_getStaticVariable", jar1);
    }

    public void test_oneJar_callInstanceMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_callInstanceMethod", jar1);
    }

    public void test_oneJar_getInstanceVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_getInstanceVariable", jar1);
    }

    // ONE_DEX

    public void test_oneDex_init() throws Exception {
        ClassLoader cl = createLoader(dex1);
    }

    public void test_oneDex_simpleUse() throws Exception {
        String result = (String) createLoaderAndCallMethod("test.Test1", "test", dex1);
        assertSame("blort", result);
    }

    public void test_oneDex_constructor() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_constructor", dex1);
    }

    public void test_oneDex_callStaticMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_callStaticMethod", dex1);
    }

    public void test_oneDex_getStaticVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_getStaticVariable", dex1);
    }

    public void test_oneDex_callInstanceMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_callInstanceMethod", dex1);
    }

    public void test_oneDex_getInstanceVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_getInstanceVariable", dex1);
    }

    // TWO_JAR

    public void test_twoJar_init() throws Exception {
        ClassLoader cl = createLoader(jar1, jar2);
    }

    public void test_twoJar_simpleUse() throws Exception {
        String result = (String) createLoaderAndCallMethod("test.Test1", "test", jar1, jar2);
        assertSame("blort", result);
    }

    public void test_twoJar_constructor() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_constructor", jar1, jar2);
    }

    public void test_twoJar_callStaticMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_callStaticMethod", jar1, jar2);
    }

    public void test_twoJar_getStaticVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_getStaticVariable", jar1, jar2);
    }

    public void test_twoJar_callInstanceMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_callInstanceMethod", jar1, jar2);
    }

    public void test_twoJar_getInstanceVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_getInstanceVariable", jar1, jar2);
    }

    public void test_twoJar_diff_constructor() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_diff_constructor", jar1, jar2);
    }

    public void test_twoJar_diff_callStaticMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_diff_callStaticMethod", jar1, jar2);
    }

    public void test_twoJar_diff_getStaticVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_diff_getStaticVariable", jar1, jar2);
    }

    public void test_twoJar_diff_callInstanceMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_diff_callInstanceMethod", jar1, jar2);
    }

    public void test_twoJar_diff_getInstanceVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_diff_getInstanceVariable", jar1, jar2);
    }

    // TWO_DEX

    public void test_twoDex_init() throws Exception {
        ClassLoader cl = createLoader(dex1, dex2);
    }

    public void test_twoDex_simpleUse() throws Exception {
        String result = (String) createLoaderAndCallMethod("test.Test1", "test", dex1, dex2);
        assertSame("blort", result);
    }

    public void test_twoDex_constructor() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_constructor", dex1, dex2);
    }

    public void test_twoDex_callStaticMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_callStaticMethod", dex1, dex2);
    }

    public void test_twoDex_getStaticVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_getStaticVariable", dex1, dex2);
    }

    public void test_twoDex_callInstanceMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_callInstanceMethod", dex1, dex2);
    }

    public void test_twoDex_getInstanceVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_getInstanceVariable", dex1, dex2);
    }

    public void test_twoDex_diff_constructor() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_diff_constructor", dex1, dex2);
    }

    public void test_twoDex_diff_callStaticMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_diff_callStaticMethod", dex1, dex2);
    }

    public void test_twoDex_diff_getStaticVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_diff_getStaticVariable", dex1, dex2);
    }

    public void test_twoDex_diff_callInstanceMethod() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_diff_callInstanceMethod", dex1, dex2);
    }

    public void test_twoDex_diff_getInstanceVariable() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_diff_getInstanceVariable", dex1, dex2);
    }

    /*
     * Tests specifically for resource-related functionality.  Since
     * raw dex files don't contain resources, these test only work
     * with jar files.
     */

    /**
     * Check that a resource in the jar file is retrievable and contains
     * the expected contents.
     */
    public void test_oneJar_directGetResourceAsStream() throws Exception {
        String result = createLoaderAndGetResource("test/Resource1.txt", jar1);
        assertEquals("Muffins are tasty!\n", result);
    }

    /**
     * Check that a resource in the jar file can be retrieved from
     * a class within that jar file.
     */
    public void test_oneJar_getResourceAsStream() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_getResourceAsStream", jar1);
    }

    public void test_twoJar_directGetResourceAsStream() throws Exception {
        String result = createLoaderAndGetResource("test/Resource1.txt", jar1, jar2);
        assertEquals("Muffins are tasty!\n", result);
    }

    public void test_twoJar_getResourceAsStream() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_getResourceAsStream", jar1, jar2);
    }

    /**
     * Check that a resource in the second jar file is retrievable and
     * contains the expected contents.
     */
    public void test_twoJar_diff_directGetResourceAsStream() throws Exception {
        String result = createLoaderAndGetResource("test2/Resource2.txt", jar1, jar2);
        assertEquals("Who doesn't like a good biscuit?\n", result);
    }

    /**
     * Check that a resource in a jar file can be retrieved from
     * a class within the other jar file.
     */
    public void test_twoJar_diff_getResourceAsStream() throws Exception {
        createLoaderAndCallMethod("test.TestMethods", "test_diff_getResourceAsStream", jar1, jar2);
    }

    /*
     * Tests native modification behaviors
     */

    /**
     * Checks that a adding a native library to an existing class loader makes it visible for
     * subsequent calls.
     * @throws Exception
     */
    public void test_oneDex_addNative_findsLibrary() throws Exception {
        String path = nativeLib1.getParentFile().getAbsolutePath();
        DexClassLoader classLoader = (DexClassLoader) createLoader(dex1);

        assertNull("findLibrary should not find un-added path",
                classLoader.findLibrary("fake"));

        classLoader.addNativePath(Collections.singletonList(path));

        assertNotNull("findLibrary should find newly added path",
                classLoader.findLibrary("fake"));
    }
}
