/*
 * 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.ArrayList;
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.
    // Need to make a copy of the dex elements since we don't want an app image with pre-resolved
    // things.
    f = pathList.getClass().getDeclaredField("dexElements");
    f.setAccessible(true);
    Object[] dexElements = (Object[]) f.get(pathList);
    f = dexElements[0].getClass().getDeclaredField("dexFile");
    f.setAccessible(true);
    for (Object element : dexElements) {
      Object dexFile = f.get(element);
      // Make copy.
      Field fileNameField = dexFile.getClass().getDeclaredField("mFileName");
      fileNameField.setAccessible(true);
      dexFiles.add(dexFile.getClass().getDeclaredConstructor(String.class).newInstance(
        fileNameField.get(dexFile)));
    }
  }

  ArrayList<Object> dexFiles = new ArrayList<Object>();
  Field dexFileField;

  protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
    // Other classes may also get loaded, ignore those.
    if (className.equals("LoadedByMyClassLoader") || className.equals("FirstSeenByMyClassLoader")) {
      System.out.println("Request for " + className);
    }

    // We're only going to handle LoadedByMyClassLoader.
    if (className != "LoadedByMyClassLoader") {
      return getParent().loadClass(className);
    }

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

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

class LoadedByMyClassLoader {
  /// CHECK-START: void LoadedByMyClassLoader.bar() inliner (before)
  /// CHECK:      LoadClass
  /// CHECK-NEXT: ClinitCheck
  /// CHECK-NEXT: InvokeStaticOrDirect
  /// CHECK-NEXT: LoadClass
  /// CHECK-NEXT: ClinitCheck
  /// CHECK-NEXT: StaticFieldGet
  /// CHECK-NEXT: LoadString
  /// CHECK-NEXT: NullCheck
  /// CHECK-NEXT: InvokeVirtual

  /// CHECK-START: void LoadedByMyClassLoader.bar() inliner (after)
  /// CHECK:      LoadClass
  /// CHECK-NEXT: ClinitCheck
                /* We inlined FirstSeenByMyClassLoader.$inline$bar */
  /// CHECK-NEXT: LoadClass
  /// CHECK-NEXT: ClinitCheck
  /// CHECK-NEXT: StaticFieldGet
  /// CHECK-NEXT: LoadString
  /// CHECK-NEXT: NullCheck
  /// CHECK-NEXT: InvokeVirtual

  /// CHECK-START: void LoadedByMyClassLoader.bar() register (before)
                /* Load and initialize FirstSeenByMyClassLoader */
  /// CHECK:      LoadClass gen_clinit_check:true
                /* Load and initialize System */
  /// CHECK-NEXT: LoadClass gen_clinit_check:true
  /// CHECK-NEXT: StaticFieldGet
  // There may be HArmDexCacheArraysBase or HX86ComputeBaseMethodAddress here.
  /// CHECK:      LoadString
  /// CHECK-NEXT: NullCheck
  /// CHECK-NEXT: InvokeVirtual
  public static void bar() {
    FirstSeenByMyClassLoader.$inline$bar();
    System.out.println("In between the two calls.");
    FirstSeenByMyClassLoader.$noinline$bar();
  }
}

public class Main {
  public static void main(String[] args) throws Exception {
    MyClassLoader o = new MyClassLoader();
    Class foo = o.loadClass("LoadedByMyClassLoader");
    Method m = foo.getDeclaredMethod("bar");
    m.invoke(null);
  }
}
