/*
 * 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 com.google.dexmaker.stock;

import com.google.dexmaker.DexMakerTest;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Arrays;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;

public class ProxyBuilderTest extends TestCase {
    private FakeInvocationHandler fakeHandler = new FakeInvocationHandler();
    private File versionedDxDir = new File(DexMakerTest.getDataDirectory(), "v1");

    public void setUp() throws Exception {
        super.setUp();
        versionedDxDir.mkdirs();
        clearVersionedDxDir();
        getGeneratedProxyClasses().clear();
    }

    public void tearDown() throws Exception {
        getGeneratedProxyClasses().clear();
        clearVersionedDxDir();
        super.tearDown();
    }

    private void clearVersionedDxDir() {
        for (File f : versionedDxDir.listFiles()) {
            f.delete();
        }
    }

    public static class SimpleClass {
        public String simpleMethod() {
            throw new AssertionFailedError();
        }
    }

    public void testExampleOperation() throws Throwable {
        fakeHandler.setFakeResult("expected");
        SimpleClass proxy = proxyFor(SimpleClass.class).build();
        assertEquals("expected", proxy.simpleMethod());
        assertEquals(2, versionedDxDir.listFiles().length);
    }

    public void testExampleOperation_DexMakerCaching() throws Throwable {
        fakeHandler.setFakeResult("expected");
        SimpleClass proxy = proxyFor(SimpleClass.class).build();
        assertEquals(2, versionedDxDir.listFiles().length);
        assertEquals("expected", proxy.simpleMethod());

        // Force ProxyBuilder to create a DexMaker generator and call DexMaker.generateAndLoad().
        getGeneratedProxyClasses().clear();

        proxy = proxyFor(SimpleClass.class).build();
        assertEquals(2, versionedDxDir.listFiles().length);
        assertEquals("expected", proxy.simpleMethod());
    }

    public static class ConstructorTakesArguments {
        private final String argument;

        public ConstructorTakesArguments(String arg) {
            argument = arg;
        }

        public String method() {
            throw new AssertionFailedError();
        }
    }

    public void testConstruction_SucceedsIfCorrectArgumentsProvided() throws Throwable {
        ConstructorTakesArguments proxy = proxyFor(ConstructorTakesArguments.class)
                .constructorArgTypes(String.class)
                .constructorArgValues("hello")
                .build();
        assertEquals("hello", proxy.argument);
        proxy.method();
    }

    public void testConstruction_FailsWithWrongNumberOfArguments() throws Throwable {
        try {
            proxyFor(ConstructorTakesArguments.class).build();
            fail();
        } catch (IllegalArgumentException expected) {}
    }

    public void testClassIsNotAccessbile_FailsWithUnsupportedOperationException() throws Exception {
        class MethodVisibilityClass {
        }
        try {
            proxyFor(MethodVisibilityClass.class).build();
            fail();
        } catch (UnsupportedOperationException expected) {}
    }

    private static class PrivateVisibilityClass {
    }

    public void testPrivateClass_FailsWithUnsupportedOperationException() throws Exception {
        try {
            proxyFor(PrivateVisibilityClass.class).build();
            fail();
        } catch (UnsupportedOperationException expected) {}
    }

    protected static class ProtectedVisibilityClass {
        public String foo() {
            throw new AssertionFailedError();
        }
    }

    public void testProtectedVisibility_WorksFine() throws Exception {
        assertEquals("fake result", proxyFor(ProtectedVisibilityClass.class).build().foo());
    }

    public static class HasFinalMethod {
        public String nonFinalMethod() {
            return "non-final method";
        }

        public final String finalMethod() {
            return "final method";
        }
    }

    public void testCanProxyClassesWithFinalMethods_WillNotCallTheFinalMethod() throws Throwable {
        HasFinalMethod proxy = proxyFor(HasFinalMethod.class).build();
        assertEquals("final method", proxy.finalMethod());
        assertEquals("fake result", proxy.nonFinalMethod());
    }

    public static class HasPrivateMethod {
        private String result() {
            return "expected";
        }
    }

    public void testProxyingPrivateMethods_NotIntercepted() throws Throwable {
        assertEquals("expected", proxyFor(HasPrivateMethod.class).build().result());
    }

    public static class HasPackagePrivateMethod {
        String result() {
            throw new AssertionFailedError();
        }
    }

    public void testProxyingPackagePrivateMethods_AreIntercepted() throws Throwable {
        assertEquals("fake result", proxyFor(HasPackagePrivateMethod.class).build().result());
    }

    public static class HasProtectedMethod {
        protected String result() {
            throw new AssertionFailedError();
        }
    }

    public void testProxyingProtectedMethods_AreIntercepted() throws Throwable {
        assertEquals("fake result", proxyFor(HasProtectedMethod.class).build().result());
    }

    public static class HasVoidMethod {
        public void dangerousMethod() {
            fail();
        }
    }

    public void testVoidMethod_ShouldNotThrowRuntimeException() throws Throwable {
        proxyFor(HasVoidMethod.class).build().dangerousMethod();
    }

    public void testObjectMethodsAreAlsoProxied() throws Throwable {
        Object proxy = proxyFor(Object.class).build();
        fakeHandler.setFakeResult("mystring");
        assertEquals("mystring", proxy.toString());
        fakeHandler.setFakeResult(-1);
        assertEquals(-1, proxy.hashCode());
        fakeHandler.setFakeResult(false);
        assertEquals(false, proxy.equals(proxy));
    }

    public static class AllReturnTypes {
        public boolean getBoolean() { return true; }
        public int getInt() { return 1; }
        public byte getByte() { return 2; }
        public long getLong() { return 3L; }
        public short getShort() { return 4; }
        public float getFloat() { return 5f; }
        public double getDouble() { return 6.0; }
        public char getChar() { return 'c'; }
        public int[] getIntArray() { return new int[] { 8, 9 }; }
        public String[] getStringArray() { return new String[] { "d", "e" }; }
    }

    public void testAllReturnTypes() throws Throwable {
        AllReturnTypes proxy = proxyFor(AllReturnTypes.class).build();
        fakeHandler.setFakeResult(false);
        assertEquals(false, proxy.getBoolean());
        fakeHandler.setFakeResult(8);
        assertEquals(8, proxy.getInt());
        fakeHandler.setFakeResult((byte) 9);
        assertEquals(9, proxy.getByte());
        fakeHandler.setFakeResult(10L);
        assertEquals(10, proxy.getLong());
        fakeHandler.setFakeResult((short) 11);
        assertEquals(11, proxy.getShort());
        fakeHandler.setFakeResult(12f);
        assertEquals(12f, proxy.getFloat());
        fakeHandler.setFakeResult(13.0);
        assertEquals(13.0, proxy.getDouble());
        fakeHandler.setFakeResult('z');
        assertEquals('z', proxy.getChar());
        fakeHandler.setFakeResult(new int[] { -1, -2 });
        assertEquals("[-1, -2]", Arrays.toString(proxy.getIntArray()));
        fakeHandler.setFakeResult(new String[] { "x", "y" });
        assertEquals("[x, y]", Arrays.toString(proxy.getStringArray()));
    }

    public static class PassThroughAllTypes {
        public boolean getBoolean(boolean input) { return input; }
        public int getInt(int input) { return input; }
        public byte getByte(byte input) { return input; }
        public long getLong(long input) { return input; }
        public short getShort(short input) { return input; }
        public float getFloat(float input) { return input; }
        public double getDouble(double input) { return input; }
        public char getChar(char input) { return input; }
        public String getString(String input) { return input; }
        public Object getObject(Object input) { return input; }
        public void getNothing() {}
    }

    public static class InvokeSuperHandler implements InvocationHandler {
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return ProxyBuilder.callSuper(proxy, method, args);
        }
    }

    public void testPassThroughWorksForAllTypes() throws Exception {
        PassThroughAllTypes proxy = proxyFor(PassThroughAllTypes.class)
                .handler(new InvokeSuperHandler())
                .build();
        assertEquals(false, proxy.getBoolean(false));
        assertEquals(true, proxy.getBoolean(true));
        assertEquals(0, proxy.getInt(0));
        assertEquals(1, proxy.getInt(1));
        assertEquals((byte) 2, proxy.getByte((byte) 2));
        assertEquals((byte) 3, proxy.getByte((byte) 3));
        assertEquals(4L, proxy.getLong(4L));
        assertEquals(5L, proxy.getLong(5L));
        assertEquals((short) 6, proxy.getShort((short) 6));
        assertEquals((short) 7, proxy.getShort((short) 7));
        assertEquals(8f, proxy.getFloat(8f));
        assertEquals(9f, proxy.getFloat(9f));
        assertEquals(10.0, proxy.getDouble(10.0));
        assertEquals(11.0, proxy.getDouble(11.0));
        assertEquals('a', proxy.getChar('a'));
        assertEquals('b', proxy.getChar('b'));
        assertEquals("asdf", proxy.getString("asdf"));
        assertEquals("qwer", proxy.getString("qwer"));
        assertEquals(null, proxy.getString(null));
        Object a = new Object();
        assertEquals(a, proxy.getObject(a));
        assertEquals(null, proxy.getObject(null));
        proxy.getNothing();
    }

    public static class ExtendsAllReturnTypes extends AllReturnTypes {
        public int example() { return 0; }
    }

    public void testProxyWorksForSuperclassMethodsAlso() throws Throwable {
        ExtendsAllReturnTypes proxy = proxyFor(ExtendsAllReturnTypes.class).build();
        fakeHandler.setFakeResult(99);
        assertEquals(99, proxy.example());
        assertEquals(99, proxy.getInt());
        assertEquals(99, proxy.hashCode());
    }

    public static class HasOddParams {
        public long method(int first, Integer second) {
            throw new AssertionFailedError();
        }
    }

    public void testMixingBoxedAndUnboxedParams() throws Throwable {
        HasOddParams proxy = proxyFor(HasOddParams.class).build();
        fakeHandler.setFakeResult(99L);
        assertEquals(99L, proxy.method(1, Integer.valueOf(2)));
    }

    public static class SingleInt {
        public String getString(int value) {
            throw new AssertionFailedError();
        }
    }

    public void testSinglePrimitiveParameter() throws Throwable {
        InvocationHandler handler = new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return "asdf" + ((Integer) args[0]).intValue();
            }
        };
        assertEquals("asdf1", proxyFor(SingleInt.class).handler(handler).build().getString(1));
    }

    public static class TwoConstructors {
        private final String string;

        public TwoConstructors() {
            string = "no-arg";
        }

        public TwoConstructors(boolean unused) {
            string = "one-arg";
        }
    }

    public void testNoConstructorArguments_CallsNoArgConstructor() throws Throwable {
        TwoConstructors twoConstructors = proxyFor(TwoConstructors.class).build();
        assertEquals("no-arg", twoConstructors.string);
    }

    public void testWithoutInvocationHandler_ThrowsIllegalArgumentException() throws Throwable {
        try {
            ProxyBuilder.forClass(TwoConstructors.class)
                    .dexCache(DexMakerTest.getDataDirectory())
                    .build();
            fail();
        } catch (IllegalArgumentException expected) {}
    }

    public static class HardToConstructCorrectly {
        public HardToConstructCorrectly() { fail(); }
        public HardToConstructCorrectly(Runnable ignored) { fail(); }
        public HardToConstructCorrectly(Exception ignored) { fail(); }
        public HardToConstructCorrectly(Boolean ignored) { /* safe */ }
        public HardToConstructCorrectly(Integer ignored) { fail(); }
    }

    public void testHardToConstruct_WorksIfYouSpecifyTheConstructorCorrectly() throws Throwable {
        proxyFor(HardToConstructCorrectly.class)
                .constructorArgTypes(Boolean.class)
                .constructorArgValues(true)
                .build();
    }

    public void testHardToConstruct_EvenWorksWhenArgsAreAmbiguous() throws Throwable {
        proxyFor(HardToConstructCorrectly.class)
                .constructorArgTypes(Boolean.class)
                .constructorArgValues(new Object[] { null })
                .build();
    }

    public void testHardToConstruct_DoesNotInferTypesFromValues() throws Throwable {
        try {
            proxyFor(HardToConstructCorrectly.class)
                    .constructorArgValues(true)
                    .build();
            fail();
        } catch (IllegalArgumentException expected) {}
    }

    public void testDefaultProxyHasSuperMethodToAccessOriginal() throws Exception {
        Object objectProxy = proxyFor(Object.class).build();
        assertNotNull(objectProxy.getClass().getMethod("super$hashCode$int"));
    }

    public static class PrintsOddAndValue {
        public String method(int value) {
            return "odd " + value;
        }
    }

    public void testSometimesDelegateToSuper() throws Exception {
        InvocationHandler delegatesOddValues = new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                if (method.getName().equals("method")) {
                    int intValue = ((Integer) args[0]).intValue();
                    if (intValue % 2 == 0) {
                        return "even " + intValue;
                    }
                }
                return ProxyBuilder.callSuper(proxy, method, args);
            }
        };
        PrintsOddAndValue proxy = proxyFor(PrintsOddAndValue.class)
                .handler(delegatesOddValues)
                .build();
        assertEquals("even 0", proxy.method(0));
        assertEquals("odd 1", proxy.method(1));
        assertEquals("even 2", proxy.method(2));
        assertEquals("odd 3", proxy.method(3));
    }
    
    public void testCallSuperThrows() throws Exception {
        InvocationHandler handler = new InvocationHandler() {
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                return ProxyBuilder.callSuper(o, method, objects);
            }
        };

        FooThrows fooThrows = proxyFor(FooThrows.class)
                .handler(handler)
                .build();

        try {
            fooThrows.foo();
            fail();
        } catch (IllegalStateException expected) {
            assertEquals("boom!", expected.getMessage());
        }
    }
    
    public static class FooThrows {
        public void foo() {
            throw new IllegalStateException("boom!");
        }
    }

    public static class DoubleReturn {
        public double getValue() {
            return 2.0;
        }
    }

    public void testUnboxedResult() throws Exception {
        fakeHandler.fakeResult = 2.0;
        assertEquals(2.0, proxyFor(DoubleReturn.class).build().getValue());
    }

    public static void staticMethod() {
    }

    public void testDoesNotOverrideStaticMethods() throws Exception {
        // Method should exist on this test class itself.
        ProxyBuilderTest.class.getDeclaredMethod("staticMethod");
        // Method should not exist on the subclass.
        try {
            proxyFor(ProxyBuilderTest.class).build().getClass().getDeclaredMethod("staticMethod");
            fail();
        } catch (NoSuchMethodException expected) {}
    }

    public void testIllegalCacheDirectory() throws Exception {
        try {
          proxyFor(ProxyForIllegalCacheDirectory.class)
                  .dexCache(new File("/poop/"))
                  .build();
          fail();
        } catch (IOException expected) {
        }
    }

    public static class ProxyForIllegalCacheDirectory {
    }

    public void testInvalidConstructorSpecification() throws Exception {
        try {
            proxyFor(Object.class)
                    .constructorArgTypes(String.class, Boolean.class)
                    .constructorArgValues("asdf", true)
                    .build();
            fail();
        } catch (IllegalArgumentException expected) {}
    }

    public static abstract class AbstractClass {
        public abstract Object getValue();
    }

    public void testAbstractClassBehaviour() throws Exception {
        assertEquals("fake result", proxyFor(AbstractClass.class).build().getValue());
    }

    public static class CtorHasDeclaredException {
        public CtorHasDeclaredException() throws IOException {
            throw new IOException();
        }
    }

    public static class CtorHasRuntimeException {
        public CtorHasRuntimeException() {
            throw new RuntimeException("my message");
        }
    }

    public static class CtorHasError {
        public CtorHasError() {
            throw new Error("my message again");
        }
    }

    public void testParentConstructorThrowsDeclaredException() throws Exception {
        try {
            proxyFor(CtorHasDeclaredException.class).build();
            fail();
        } catch (UndeclaredThrowableException expected) {
            assertTrue(expected.getCause() instanceof IOException);
        }
        try {
            proxyFor(CtorHasRuntimeException.class).build();
            fail();
        } catch (RuntimeException expected) {
            assertEquals("my message", expected.getMessage());
        }
        try {
            proxyFor(CtorHasError.class).build();
            fail();
        } catch (Error expected) {
            assertEquals("my message again", expected.getMessage());
        }
    }

    public void testGetInvocationHandler_NormalOperation() throws Exception {
        Object proxy = proxyFor(Object.class).build();
        assertSame(fakeHandler, ProxyBuilder.getInvocationHandler(proxy));
    }

    public void testGetInvocationHandler_NotAProxy() {
        try {
            ProxyBuilder.getInvocationHandler(new Object());
            fail();
        } catch (IllegalArgumentException expected) {}
    }

    public static class ReturnsObject {
        public Object getValue() {
            return new Object();
        }
    }

    public static class ReturnsString extends ReturnsObject {
        @Override
        public String getValue() {
            return "a string";
        }
    }

    public void testCovariantReturnTypes_NormalBehaviour() throws Exception {
        String expected = "some string";
        fakeHandler.setFakeResult(expected);
        assertSame(expected, proxyFor(ReturnsObject.class).build().getValue());
        assertSame(expected, proxyFor(ReturnsString.class).build().getValue());
    }

    public void testCovariantReturnTypes_WrongReturnType() throws Exception {
        try {
            fakeHandler.setFakeResult(new Object());
            proxyFor(ReturnsString.class).build().getValue();
            fail();
        } catch (ClassCastException expected) {}
    }

    public void testCaching() throws Exception {
        SimpleClass a = proxyFor(SimpleClass.class).build();
        SimpleClass b = proxyFor(SimpleClass.class).build();
        assertSame(a.getClass(), b.getClass());
    }

    public void testCachingWithMultipleConstructors() throws Exception {
        HasMultipleConstructors a = ProxyBuilder.forClass(HasMultipleConstructors.class)
                .constructorArgTypes()
                .constructorArgValues()
                .handler(fakeHandler)
                .dexCache(DexMakerTest.getDataDirectory()).build();
        assertEquals("no args", a.calledConstructor);
        HasMultipleConstructors b = ProxyBuilder.forClass(HasMultipleConstructors.class)
                .constructorArgTypes(int.class)
                .constructorArgValues(2)
                .handler(fakeHandler)
                .dexCache(DexMakerTest.getDataDirectory()).build();
        assertEquals("int 2", b.calledConstructor);
        assertEquals(a.getClass(), b.getClass());

        HasMultipleConstructors c = ProxyBuilder.forClass(HasMultipleConstructors.class)
                .constructorArgTypes(Integer.class)
                .constructorArgValues(3)
                .handler(fakeHandler)
                .dexCache(DexMakerTest.getDataDirectory()).build();
        assertEquals("Integer 3", c.calledConstructor);
        assertEquals(a.getClass(), c.getClass());
    }

    public static class HasMultipleConstructors {
        private final String calledConstructor;
        public HasMultipleConstructors() {
            calledConstructor = "no args";
        }
        public HasMultipleConstructors(int b) {
            calledConstructor = "int " + b;
        }
        public HasMultipleConstructors(Integer c) {
            calledConstructor = "Integer " + c;
        }
    }

    public void testClassNotCachedWithDifferentParentClassLoaders() throws Exception {
        ClassLoader classLoaderA = newPathClassLoader();
        SimpleClass a = proxyFor(SimpleClass.class)
                .parentClassLoader(classLoaderA)
                .build();
        assertEquals(classLoaderA, a.getClass().getClassLoader().getParent());

        ClassLoader classLoaderB = newPathClassLoader();
        SimpleClass b = proxyFor(SimpleClass.class)
                .parentClassLoader(classLoaderB)
                .build();
        assertEquals(classLoaderB, b.getClass().getClassLoader().getParent());

        assertTrue(a.getClass() != b.getClass());
    }
    
    public void testAbstractClassWithUndeclaredInterfaceMethod() throws Throwable {
        DeclaresInterface declaresInterface = proxyFor(DeclaresInterface.class)
                .build();
        assertEquals("fake result", declaresInterface.call());
        try {
            ProxyBuilder.callSuper(declaresInterface, Callable.class.getMethod("call"));
            fail();
        } catch (AbstractMethodError expected) {
        }
    }
    
    public static abstract class DeclaresInterface implements Callable<String> {
    }

    public void testImplementingInterfaces() throws Throwable {
        SimpleClass simpleClass = proxyFor(SimpleClass.class)
                .implementing(Callable.class)
                .implementing(Comparable.class)
                .build();
        assertEquals("fake result", simpleClass.simpleMethod());

        Callable<?> asCallable = (Callable<?>) simpleClass;
        assertEquals("fake result", asCallable.call());

        Comparable<?> asComparable = (Comparable<?>) simpleClass;
        fakeHandler.fakeResult = 3;
        assertEquals(3, asComparable.compareTo(null));
    }

    public void testCallSuperWithInterfaceMethod() throws Throwable {
        SimpleClass simpleClass = proxyFor(SimpleClass.class)
                .implementing(Callable.class)
                .build();
        try {
            ProxyBuilder.callSuper(simpleClass, Callable.class.getMethod("call"));
            fail();
        } catch (AbstractMethodError expected) {
        } catch (NoSuchMethodError expected) {
        }
    }

    public void testImplementInterfaceCallingThroughConcreteClass() throws Throwable {
        InvocationHandler invocationHandler = new InvocationHandler() {
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                assertEquals("a", ProxyBuilder.callSuper(o, method, objects));
                return "b";
            }
        };
        ImplementsCallable proxy = proxyFor(ImplementsCallable.class)
                .implementing(Callable.class)
                .handler(invocationHandler)
                .build();
        assertEquals("b", proxy.call());
        assertEquals("a", ProxyBuilder.callSuper(
                proxy, ImplementsCallable.class.getMethod("call")));
    }
    
    /**
     * This test is a bit unintuitive because it exercises the synthetic methods
     * that support covariant return types. Calling 'Object call()' on the
     * interface bridges to 'String call()', and so the super method appears to
     * also be proxied.
     */
    public void testImplementInterfaceCallingThroughInterface() throws Throwable {
        final AtomicInteger count = new AtomicInteger();

        InvocationHandler invocationHandler = new InvocationHandler() {
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                count.incrementAndGet();
                return ProxyBuilder.callSuper(o, method, objects);
            }
        };

        Callable<?> proxy = proxyFor(ImplementsCallable.class)
                .implementing(Callable.class)
                .handler(invocationHandler)
                .build();

        // the invocation handler is called twice!
        assertEquals("a", proxy.call());
        assertEquals(2, count.get());

        // the invocation handler is called, even though this is a callSuper() call!
        assertEquals("a", ProxyBuilder.callSuper(proxy, Callable.class.getMethod("call")));
        assertEquals(3, count.get());
    }
    
    public static class ImplementsCallable implements Callable<String> {
        public String call() throws Exception {
            return "a";
        }
    }

    /**
     * This test shows that our generated proxies follow the bytecode convention
     * where methods can have the same name but unrelated return types. This is
     * different from javac's convention where return types must be assignable
     * in one direction or the other.
     */
    public void testInterfacesSameNamesDifferentReturnTypes() throws Throwable {
        InvocationHandler handler = new InvocationHandler() {
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                if (method.getReturnType() == void.class) {
                    return null;
                } else if (method.getReturnType() == String.class) {
                    return "X";
                } else if (method.getReturnType() == int.class) {
                    return 3;
                } else {
                    throw new AssertionFailedError();
                }
            }
        };
        
        Object o = proxyFor(Object.class)
                .implementing(FooReturnsVoid.class, FooReturnsString.class, FooReturnsInt.class)
                .handler(handler)
                .build();
        
        FooReturnsVoid a = (FooReturnsVoid) o;
        a.foo();
        
        FooReturnsString b = (FooReturnsString) o;
        assertEquals("X", b.foo());
        
        FooReturnsInt c = (FooReturnsInt) o;
        assertEquals(3, c.foo());
    }
    
    public void testInterfacesSameNamesSameReturnType() throws Throwable {
        Object o = proxyFor(Object.class)
                .implementing(FooReturnsInt.class, FooReturnsInt2.class)
                .build();
        
        fakeHandler.setFakeResult(3);

        FooReturnsInt a = (FooReturnsInt) o;
        assertEquals(3, a.foo());

        FooReturnsInt2 b = (FooReturnsInt2) o;
        assertEquals(3, b.foo());
    }
    
    public interface FooReturnsVoid {
        void foo();
    }

    public interface FooReturnsString {
        String foo();
    }

    public interface FooReturnsInt {
        int foo();
    }
    
    public interface FooReturnsInt2 {
        int foo();
    }
    
    private ClassLoader newPathClassLoader() throws Exception {
        return (ClassLoader) Class.forName("dalvik.system.PathClassLoader")
                .getConstructor(String.class, ClassLoader.class)
                .newInstance("", getClass().getClassLoader());

    }

    public void testSubclassOfRandom() throws Exception {
        proxyFor(Random.class)
                .handler(new InvokeSuperHandler())
                .build();
    }

    public static class FinalToString {
        @Override public final String toString() {
            return "no proxy";
        }
    }

    // https://code.google.com/p/dexmaker/issues/detail?id=12
    public void testFinalToString() throws Throwable {
        assertEquals("no proxy", proxyFor(FinalToString.class).build().toString());
    }

    /** Simple helper to add the most common args for this test to the proxy builder. */
    private <T> ProxyBuilder<T> proxyFor(Class<T> clazz) throws Exception {
        return ProxyBuilder.forClass(clazz)
                .handler(fakeHandler)
                .dexCache(DexMakerTest.getDataDirectory());
    }

    private static class FakeInvocationHandler implements InvocationHandler {
        private Object fakeResult = "fake result";

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return fakeResult;
        }

        public void setFakeResult(Object result) {
            fakeResult = result;
        }
    }

    public static class TestOrderingClass {
        public int returnsInt() {
            return 0;
        }

        public int returnsInt(int param1, int param2) {
            return 1;
        }

        public String returnsString() {
            return "string";
        }

        public boolean returnsBoolean() {
            return false;
        }

        public double returnsDouble() {
            return 1.0;
        }

        public Object returnsObject() {
            return new Object();
        }
    }

    @SuppressWarnings("unchecked")
    public void testMethodsGeneratedInDeterministicOrder() throws Exception {
        // Grab the static methods array from the original class.
        Method[] methods1 = getMethodsForProxyClass(TestOrderingClass.class);
        assertNotNull(methods1);

        // Clear ProxyBuilder's in-memory cache of classes. This will force
        // it to rebuild the class and reset the static methods field.
        Map<Class<?>, Class<?>> map = getGeneratedProxyClasses();
        assertNotNull(map);
        map.clear();

        // Grab the static methods array from the rebuilt class.
        Method[] methods2 = getMethodsForProxyClass(TestOrderingClass.class);
        assertNotNull(methods2);

        // Ensure that the two method arrays are equal.
        assertTrue(Arrays.equals(methods1, methods2));
    }

    public void testOrderingClassWithDexMakerCaching() throws Exception {
        doTestOrderClassWithDexMakerCaching();

        // Force ProxyBuilder to call DexMaker.generateAndLoad()
        getGeneratedProxyClasses().clear();

        doTestOrderClassWithDexMakerCaching();
    }

    private void doTestOrderClassWithDexMakerCaching() throws Exception {
        TestOrderingClass proxy = ProxyBuilder.forClass(TestOrderingClass.class)
                .handler(new InvokeSuperHandler())
                .dexCache(DexMakerTest.getDataDirectory())
                .build();
        assertEquals(0, proxy.returnsInt());
        assertEquals(1, proxy.returnsInt(1, 1));
        assertEquals("string", proxy.returnsString());
        assertFalse(proxy.returnsBoolean());
        assertEquals(1.0, proxy.returnsDouble());
        assertNotNull(proxy.returnsObject());
        assertEquals(2, versionedDxDir.listFiles().length);
    }

    // Returns static methods array from a proxy class.
    private Method[] getMethodsForProxyClass(Class<?> parentClass) throws Exception {
        Class<?> proxyClass = proxyFor(parentClass).buildProxyClass();
        Method[] methods = null;
        for (Field f : proxyClass.getDeclaredFields()) {
            if (Method[].class.isAssignableFrom(f.getType())) {
                f.setAccessible(true);
                methods = (Method[]) f.get(null);
                break;
            }
        }

        return methods;
    }

    private Map<Class<?>, Class<?>> getGeneratedProxyClasses() throws Exception {
        Field mapField = ProxyBuilder.class
                .getDeclaredField("generatedProxyClasses");
        mapField.setAccessible(true);
        return (Map<Class<?>, Class<?>>) mapField.get(null);
    }

    public static class ConcreteClassA implements FooReturnsInt {
        // from FooReturnsInt
        public int foo() {
            return 1;
        }

        // not from FooReturnsInt
        public String bar() {
            return "bar";
        }
    }

    public static class ConcreteClassB implements FooReturnsInt {
        // from FooReturnsInt
        public int foo() {
            return 0;
        }

        // not from FooReturnsInt
        public String bar() {
            return "bahhr";
        }
    }

    public void testTwoClassesWithIdenticalMethodSignatures_DexMakerCaching() throws Exception {
        ConcreteClassA proxyA = ProxyBuilder.forClass(ConcreteClassA.class)
                .handler(new InvokeSuperHandler())
                .dexCache(DexMakerTest.getDataDirectory())
                .build();
        assertEquals(1, proxyA.foo());
        assertEquals("bar", proxyA.bar());
        assertEquals(2, versionedDxDir.listFiles().length);

        ConcreteClassB proxyB = ProxyBuilder.forClass(ConcreteClassB.class)
                .handler(new InvokeSuperHandler())
                .dexCache(DexMakerTest.getDataDirectory())
                .build();
        assertEquals(0, proxyB.foo());
        assertEquals("bahhr", proxyB.bar());
        assertEquals(4, versionedDxDir.listFiles().length);
    }
}
