/*
 * Copyright (C) 2015 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.Field;
import java.lang.reflect.Method;
import java.util.List;

class MyClassLoader extends ClassLoader {
  MyClassLoader() throws Exception {
    super(MyClassLoader.class.getClassLoader());

    // Some magic to get access to the pathList field of BaseDexClassLoader.
    ClassLoader loader = getClass().getClassLoader();
    Class<?> baseDexClassLoader = loader.getClass().getSuperclass();
    Field f = baseDexClassLoader.getDeclaredField("pathList");
    f.setAccessible(true);
    Object pathList = f.get(loader);

    // Some magic to get access to the dexField field of pathList.
    f = pathList.getClass().getDeclaredField("dexElements");
    f.setAccessible(true);
    dexElements = (Object[]) f.get(pathList);
    dexFileField = dexElements[0].getClass().getDeclaredField("dexFile");
    dexFileField.setAccessible(true);
  }

  Object[] dexElements;
  Field dexFileField;

  static ClassLoader level1ClassLoader;

  protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
    if (this != level1ClassLoader) {
      if (className.equals("Level1")) {
        return level1ClassLoader.loadClass(className);
      } else if (className.equals("Level2")) {
        throw new ClassNotFoundException("None of my methods require Level2!");
      } else if (!className.equals("LoadedByMyClassLoader")) {
        // We're only going to handle LoadedByMyClassLoader.
        return getParent().loadClass(className);
      }
    } else {
      if (className != "Level1" && className != "Level2") {
        return getParent().loadClass(className);
      }
    }

    // Mimic what DexPathList.findClass is doing.
    try {
      for (Object element : dexElements) {
        Object dex = dexFileField.get(element);
        Method method = dex.getClass().getDeclaredMethod(
            "loadClassBinaryName", String.class, ClassLoader.class, List.class);

        if (dex != null) {
          Class clazz = (Class)method.invoke(dex, className, this, null);
          if (clazz != null) {
            return clazz;
          }
        }
      }
    } catch (Exception e) { /* Ignore */ }
    return null;
  }
}

class LoadedByMyClassLoader {
  public static void bar() {
    Level1.$inline$bar();
  }
}

class Main {
  public static void main(String[] args) throws Exception {
    System.loadLibrary(args[0]);
    // Clone resolved methods, to restore the original version just
    // before we walk the stack in $noinline$bar.
    savedResolvedMethods = cloneResolvedMethods(Main.class);

    MyClassLoader o = new MyClassLoader();
    MyClassLoader.level1ClassLoader = new MyClassLoader();
    Class foo = o.loadClass("LoadedByMyClassLoader");
    Method m = foo.getDeclaredMethod("bar");
    try {
      m.invoke(null);
    } catch (Error e) { /* Ignore */ }
  }

  public static void $inline$bar() {
  }

  public static void $noinline$bar() {
    try {
      // Be evil and clear all dex cache entries.
      Field f = Class.class.getDeclaredField("dexCache");
      f.setAccessible(true);
      Object dexCache = f.get(Main.class);
      f = dexCache.getClass().getDeclaredField("resolvedTypes");
      f.setAccessible(true);
      Object[] array = (Object[]) f.get(dexCache);
      for (int i = 0; i < array.length; i++) {
        array[i] = null;
      }
      restoreResolvedMethods(Main.class, savedResolvedMethods);
    } catch (Throwable t) { /* Ignore */ }

    // This will walk the stack, trying to resolve methods in it.
    // Because we cleared dex cache entries, we will have to find
    // classes again, which require to use the correct class loader
    // in the presence of inlining.
    new Exception().printStackTrace();
  }
  static Object savedResolvedMethods;

  static native Object cloneResolvedMethods(Class<?> cls);
  static native void restoreResolvedMethods(Class<?> cls, Object saved);
}
