/*
 * Copyright (C) 2008 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.
 */

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

/**
 * Class loader test.
 */
public class Main {
    /**
     * Main entry point.
     */
    public static void main(String[] args) throws Exception {
        FancyLoader loader;

        loader = new FancyLoader(ClassLoader.getSystemClassLoader());
        //System.out.println("SYSTEM: " + ClassLoader.getSystemClassLoader());
        //System.out.println("ALTERN: " + loader);

        /*
         * This statement has no effect on this program, but it can
         * change the point where a LinkageException is thrown in
         * testImplement().  When this is present the "reference
         * implementation" throws an exception from Class.newInstance(),
         * when it's absent the exception is deferred until the first time
         * we call a method that isn't actually implemented.
         *
         * This isn't the class that fails -- it's a class with the same
         * name in the "fancy" class loader --  but the VM thinks it has a
         * reference to one of these; presumably the difference is that
         * without this the VM finds itself holding a reference to an
         * instance of an uninitialized class.
         */
        System.out.println("base: " + DoubledImplement.class);
        System.out.println("base2: " + DoubledImplement2.class);

        /*
         * Run tests.
         */
        testAccess1(loader);
        testAccess2(loader);
        testAccess3(loader);

        testExtend(loader);
        testExtendOkay(loader);
        testInterface(loader);
        testAbstract(loader);
        testImplement(loader);
        testIfaceImplement(loader);

        testSeparation();

        testClassForName();

        testNullClassLoader();
    }

    static void testNullClassLoader() {
        try {
            /* this is the "alternate" DEX/Jar file */
            String DEX_FILE = System.getenv("DEX_LOCATION") + "/068-classloader-ex.jar";
            /* on Dalvik, this is a DexFile; otherwise, it's null */
            Class<?> mDexClass = Class.forName("dalvik.system.DexFile");
            Constructor<?> ctor = mDexClass.getConstructor(String.class);
            Object mDexFile = ctor.newInstance(DEX_FILE);
            Method meth = mDexClass.getMethod("loadClass", String.class, ClassLoader.class);
            Object klass = meth.invoke(mDexFile, "Mutator", null);
            if (klass == null) {
                throw new AssertionError("loadClass with nullclass loader failed");
            }
        } catch (Exception e) {
            System.out.println(e);
        }
        System.out.println("Loaded class into null class loader");
    }

    static void testSeparation() {
        FancyLoader loader1 = new FancyLoader(ClassLoader.getSystemClassLoader());
        FancyLoader loader2 = new FancyLoader(ClassLoader.getSystemClassLoader());

        try {
            Class<?> target1 = loader1.loadClass("MutationTarget");
            Class<?> target2 = loader2.loadClass("MutationTarget");

            if (target1 == target2) {
                throw new RuntimeException("target1 should not be equal to target2");
            }

            Class<?> mutator1 = loader1.loadClass("Mutator");
            Class<?> mutator2 = loader2.loadClass("Mutator");

            if (mutator1 == mutator2) {
                throw new RuntimeException("mutator1 should not be equal to mutator2");
            }

            runMutator(mutator1, 1);

            int value = getMutationTargetValue(target1);
            if (value != 1) {
                throw new RuntimeException("target 1 has unexpected value " + value);
            }
            value = getMutationTargetValue(target2);
            if (value != 0) {
                throw new RuntimeException("target 2 has unexpected value " + value);
            }

            runMutator(mutator2, 2);

            value = getMutationTargetValue(target1);
            if (value != 1) {
                throw new RuntimeException("target 1 has unexpected value " + value);
            }
            value = getMutationTargetValue(target2);
            if (value != 2) {
                throw new RuntimeException("target 2 has unexpected value " + value);
            }
        } catch (Exception ex) {
            ex.printStackTrace(System.out);
        }
    }

    private static void runMutator(Class<?> c, int v) throws Exception {
        java.lang.reflect.Method m = c.getDeclaredMethod("mutate", int.class);
        m.invoke(null, v);
    }

    private static int getMutationTargetValue(Class<?> c) throws Exception {
        java.lang.reflect.Field f = c.getDeclaredField("value");
        return f.getInt(null);
    }

    /**
     * See if we can load a class that isn't public to us.  We should be
     * able to load it but not instantiate it.
     */
    static void testAccess1(ClassLoader loader) {
        Class<?> altClass;

        try {
            altClass = loader.loadClass("Inaccessible1");
        } catch (ClassNotFoundException cnfe) {
            System.out.println("loadClass failed");
            cnfe.printStackTrace(System.out);
            return;
        }

        /* instantiate */
        Object obj;
        try {
            obj = altClass.newInstance();
            System.out.println("ERROR: Inaccessible1 was accessible");
        } catch (InstantiationException ie) {
            System.out.println("newInstance failed: " + ie);
            return;
        } catch (IllegalAccessException iae) {
            System.out.println("Got expected access exception #1");
            //System.out.println("+++ " + iae);
            return;
        }
    }

    /**
     * See if we can load a class whose base class is not accessible to it
     * (though the base *is* accessible to us).
     */
    static void testAccess2(ClassLoader loader) {
        Class<?> altClass;

        try {
            altClass = loader.loadClass("Inaccessible2");
            System.out.println("ERROR: Inaccessible2 was accessible: " + altClass);
        } catch (ClassNotFoundException cnfe) {
            Throwable cause = cnfe.getCause();
            if (cause instanceof IllegalAccessError) {
                System.out.println("Got expected CNFE/IAE #2");
            } else {
                System.out.println("Got unexpected CNFE/IAE #2");
                cnfe.printStackTrace(System.out);
            }
        }
    }

    /**
     * See if we can load a class with an inaccessible interface.
     */
    static void testAccess3(ClassLoader loader) {
        Class<?> altClass;

        try {
            altClass = loader.loadClass("Inaccessible3");
            System.out.println("ERROR: Inaccessible3 was accessible: " + altClass);
        } catch (ClassNotFoundException cnfe) {
            Throwable cause = cnfe.getCause();
            if (cause instanceof IllegalAccessError) {
                System.out.println("Got expected CNFE/IAE #3");
            } else {
                System.out.println("Got unexpected CNFE/IAE #3");
                cnfe.printStackTrace(System.out);
            }
        }
    }

    /**
     * Test a doubled class that extends the base class.
     */
    static void testExtend(ClassLoader loader) {
        Class<?> doubledExtendClass;
        Object obj;

        /* get the "alternate" version of DoubledExtend */
        try {
            doubledExtendClass = loader.loadClass("DoubledExtend");
            //System.out.println("+++ DoubledExtend is " + doubledExtendClass
            //    + " in " + doubledExtendClass.getClassLoader());
        } catch (ClassNotFoundException cnfe) {
            System.out.println("loadClass failed: " + cnfe);
            return;
        }

        /* instantiate */
        try {
            obj = doubledExtendClass.newInstance();
        } catch (InstantiationException ie) {
            System.out.println("newInstance failed: " + ie);
            return;
        } catch (IllegalAccessException iae) {
            System.out.println("newInstance failed: " + iae);
            return;
        } catch (LinkageError le) {
            System.out.println("Got expected LinkageError on DE");
            return;
        }

        /* use the base class reference to get a CL-specific instance */
        Base baseRef = (Base) obj;
        DoubledExtend de = baseRef.getExtended();

        /* try to call through it */
        try {
            String result;

            result = Base.doStuff(de);
            System.out.println("ERROR: did not get LinkageError on DE");
            System.out.println("(result=" + result + ")");
        } catch (LinkageError le) {
            System.out.println("Got expected LinkageError on DE");
            return;
        }
    }

    /**
     * Test a doubled class that extends the base class, but is okay since
     * it doesn't override the base class method.
     */
    static void testExtendOkay(ClassLoader loader) {
        Class<?> doubledExtendOkayClass;
        Object obj;

        /* get the "alternate" version of DoubledExtendOkay */
        try {
            doubledExtendOkayClass = loader.loadClass("DoubledExtendOkay");
        } catch (ClassNotFoundException cnfe) {
            System.out.println("loadClass failed: " + cnfe);
            return;
        }

        /* instantiate */
        try {
            obj = doubledExtendOkayClass.newInstance();
        } catch (InstantiationException ie) {
            System.out.println("newInstance failed: " + ie);
            return;
        } catch (IllegalAccessException iae) {
            System.out.println("newInstance failed: " + iae);
            return;
        } catch (LinkageError le) {
            System.out.println("Got unexpected LinkageError on DEO");
            le.printStackTrace(System.out);
            return;
        }

        /* use the base class reference to get a CL-specific instance */
        BaseOkay baseRef = (BaseOkay) obj;
        DoubledExtendOkay de = baseRef.getExtended();

        /* try to call through it */
        try {
            String result;

            result = BaseOkay.doStuff(de);
            System.out.println("Got DEO result " + result);
        } catch (LinkageError le) {
            System.out.println("Got unexpected LinkageError on DEO");
            le.printStackTrace(System.out);
            return;
        }
    }

    /**
     * Try to access a doubled class through a class that implements
     * an interface declared in a different class.
     */
    static void testInterface(ClassLoader loader) {
        Class<?> getDoubledClass;
        Object obj;

        /* get GetDoubled from the "alternate" class loader */
        try {
            getDoubledClass = loader.loadClass("GetDoubled");
        } catch (ClassNotFoundException cnfe) {
            System.out.println("loadClass failed: " + cnfe);
            return;
        }

        /* instantiate */
        try {
            obj = getDoubledClass.newInstance();
        } catch (InstantiationException ie) {
            System.out.println("newInstance failed: " + ie);
            return;
        } catch (IllegalAccessException iae) {
            System.out.println("newInstance failed: " + iae);
            return;
        } catch (LinkageError le) {
            // Dalvik bails here
            System.out.println("Got LinkageError on GD");
            return;
        }

        /*
         * Cast the object to the interface, and try to use it.
         */
        IGetDoubled iface = (IGetDoubled) obj;
        try {
            /* "de" will be the wrong variety of DoubledExtendOkay */
            DoubledExtendOkay de = iface.getDoubled();
            // reference impl bails here
            String str = de.getStr();
        } catch (LinkageError le) {
            System.out.println("Got LinkageError on GD");
            return;
        }
        System.out.println("Should have failed by now on GetDoubled");
    }

    /**
     * Throw an abstract class into the middle and see what happens.
     */
    static void testAbstract(ClassLoader loader) {
        Class<?> abstractGetClass;
        Object obj;

        /* get AbstractGet from the "alternate" loader */
        try {
            abstractGetClass = loader.loadClass("AbstractGet");
        } catch (ClassNotFoundException cnfe) {
            System.out.println("loadClass ta failed: " + cnfe);
            return;
        }

        /* instantiate */
        try {
            obj = abstractGetClass.newInstance();
        } catch (InstantiationException ie) {
            System.out.println("newInstance failed: " + ie);
            return;
        } catch (IllegalAccessException iae) {
            System.out.println("newInstance failed: " + iae);
            return;
        } catch (LinkageError le) {
            System.out.println("Got LinkageError on TA");
            return;
        }

        /* use the base class reference to get a CL-specific instance */
        BaseOkay baseRef = (BaseOkay) obj;
        DoubledExtendOkay de = baseRef.getExtended();

        /* try to call through it */
        try {
            String result;

            result = BaseOkay.doStuff(de);
        } catch (LinkageError le) {
            System.out.println("Got LinkageError on TA");
            return;
        }
        System.out.println("Should have failed by now in testAbstract");
    }

    /**
     * Test a doubled class that implements a common interface.
     */
    static void testImplement(ClassLoader loader) {
        Class<?> doubledImplementClass;
        Object obj;

        useImplement(new DoubledImplement(), true);

        /* get the "alternate" version of DoubledImplement */
        try {
            doubledImplementClass = loader.loadClass("DoubledImplement");
        } catch (ClassNotFoundException cnfe) {
            System.out.println("loadClass failed: " + cnfe);
            return;
        }

        /* instantiate */
        try {
            obj = doubledImplementClass.newInstance();
        } catch (InstantiationException ie) {
            System.out.println("newInstance failed: " + ie);
            return;
        } catch (IllegalAccessException iae) {
            System.out.println("newInstance failed: " + iae);
            return;
        } catch (LinkageError le) {
            System.out.println("Got LinkageError on DI (early)");
            return;
        }

        /* if we lived this long, try to do something with it */
        ICommon icommon = (ICommon) obj;
        useImplement(icommon.getDoubledInstance(), false);
    }

    /**
     * Do something with a DoubledImplement instance.
     */
    static void useImplement(DoubledImplement di, boolean isOne) {
        //System.out.println("useObject: " + di.toString() + " -- "
        //    + di.getClass().getClassLoader());
        try {
            di.one();
            if (!isOne) {
                System.out.println("ERROR: did not get LinkageError on DI");
            }
        } catch (LinkageError le) {
            if (!isOne) {
                System.out.println("Got LinkageError on DI (late)");
            } else {
                throw le;
            }
        }
    }


    /**
     * Test a class that implements an interface with a super-interface
     * that refers to a doubled class.
     */
    static void testIfaceImplement(ClassLoader loader) {
        Class<?> ifaceImplClass;
        Object obj;

        /*
         * Create an instance of IfaceImpl.  We also pull in
         * DoubledImplement2 from the other class loader; without this
         * we don't fail in some implementations.
         */
        try {
            ifaceImplClass = loader.loadClass("IfaceImpl");
            ifaceImplClass = loader.loadClass("DoubledImplement2");
        } catch (ClassNotFoundException cnfe) {
            System.out.println("loadClass failed: " + cnfe);
            return;
        }

        /* instantiate */
        try {
            obj = ifaceImplClass.newInstance();
        } catch (InstantiationException ie) {
            System.out.println("newInstance failed: " + ie);
            return;
        } catch (IllegalAccessException iae) {
            System.out.println("newInstance failed: " + iae);
            return;
        } catch (LinkageError le) {
            System.out.println("Got LinkageError on IDI (early)");
            //System.out.println(le);
            return;
        }

        /*
         * Without the pre-load of FancyLoader->DoubledImplement2, some
         * implementations will happily execute through this part.  "obj"
         * comes from FancyLoader, but the di2 returned from ifaceSuper
         * comes from the application class loader.
         */
        IfaceSuper ifaceSuper = (IfaceSuper) obj;
        DoubledImplement2 di2 = ifaceSuper.getDoubledInstance2();
        di2.one();
    }

    static void testClassForName() throws Exception {
        System.out.println(Class.forName("Main").toString());
        try {
            System.out.println(Class.forName("Main", false, null).toString());
        } catch (ClassNotFoundException expected) {
            System.out.println("Got expected ClassNotFoundException");
        }
    }
}
