/*
 * Copyright (C) 2017 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 dalvik.system;

import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;

import android.annotation.SystemApi;

import sun.misc.CompoundEnumeration;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;

import libcore.util.NonNull;
import libcore.util.Nullable;

/**
 * A {@code ClassLoader} implementation that implements a <b>delegate last</b> lookup policy.
 * For every class or resource this loader is requested to load, the following lookup order
 * is employed:
 *
 * <ul>
 *     <li>The boot classpath is always searched first</li>
 *     <li>Then, the list of {@code dex} files associated with this classloaders's
 *     {@code dexPath} is searched.</li>
 *     <li>Finally, this classloader will delegate to the specified {@code parent}.</li>
 * </ul>
 */
public final class DelegateLastClassLoader extends PathClassLoader {

    /**
     * Whether resource loading delegates to the parent class loader. True by default.
     */
    private final boolean delegateResourceLoading;

    /**
     * Equivalent to calling {@link #DelegateLastClassLoader(String, String, ClassLoader, boolean)}
     * with {@code librarySearchPath = null, delegateResourceLoading = true}.
     */
    public DelegateLastClassLoader(String dexPath, ClassLoader parent) {
        this(dexPath, null, parent, true);
    }

    /**
     * Equivalent to calling {@link #DelegateLastClassLoader(String, String, ClassLoader, boolean)}
     * with {@code delegateResourceLoading = true}.
     */
    public DelegateLastClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
        this(dexPath, librarySearchPath, parent, true);
    }

    /**
     * Creates a {@code DelegateLastClassLoader} that operates on a given {@code dexPath}
     * and a {@code librarySearchPath}.
     *
     * The {@code dexPath} should consist of one or more of the following, separated by
     * {@code File.pathSeparator}, which is {@code ":"} on Android.
     *
     * <ul>
     * <li>JAR/ZIP/APK files, possibly containing a "classes.dex" file as well as arbitrary
     * resources.
     * <li>Raw ".dex" files (not inside a zip file).
     * </ul>
     *
     * Unlike {@link PathClassLoader}, this classloader will attempt to locate classes
     * (or resources) using the following lookup order.
     * <ul>
     *     <li>The boot classpath is always searched first.</li>
     *     <li>Then, the list of {@code dex} files contained in {@code dexPath} is searched./li>
     *     <li>Lastly, this classloader will delegate to the specified {@code parent}.</li>
     * </ul>
     *
     * Note that this is in contrast to other standard classloaders that follow the delegation
     * model. In those classloaders, the {@code parent} is always searched first.
     *
     * {@code librarySearchPath} specifies one more directories containing native library files,
     * separated by {@code File.pathSeparator}.
     *
     * @param dexPath the list of jar/apk files containing classes and resources, delimited by
     *                {@code File.pathSeparator}, which defaults to {@code ":"} on Android.
     * @param librarySearchPath the list of directories containing native libraries, delimited
     *                          by {@code File.pathSeparator}; may be {@code null}.
     * @param parent the parent class loader. May be {@code null} for the boot classloader.
     * @param delegateResourceLoading whether to delegate resource loading to the parent if
     *                                the resource is not found. This does not affect class
     *                                loading delegation.
     */

    public DelegateLastClassLoader(@NonNull String dexPath, @Nullable String librarySearchPath,
            @Nullable ClassLoader parent, boolean delegateResourceLoading) {
        super(dexPath, librarySearchPath, parent);
        this.delegateResourceLoading = delegateResourceLoading;
    }

    /**
     * Creates a {@code DelegateLastClassLoader} that operates on a given {@code dexPath}
     * and a {@code librarySearchPath}.
     *
     * The {@code dexPath} should consist of one or more of the following, separated by
     * {@code File.pathSeparator}, which is {@code ":"} on Android.
     *
     * <ul>
     * <li>JAR/ZIP/APK files, possibly containing a "classes.dex" file as well as arbitrary
     * resources.
     * <li>Raw ".dex" files (not inside a zip file).
     * </ul>
     *
     * @param dexPath the list of jar/apk files containing classes and resources, delimited by
     *                {@code File.pathSeparator}, which defaults to {@code ":"} on Android.
     * @param librarySearchPath the list of directories containing native libraries, delimited
     *                          by {@code File.pathSeparator}; may be {@code null}.
     * @param parent the parent class loader. May be {@code null} for the boot classloader.
     * @param sharedLibraryLoaders class loaders of Java shared libraries
     *                             used by this new class loader. The shared library loaders are
     *                             always checked before the {@code dexPath} when looking
     *                             up classes and resources.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public DelegateLastClassLoader(
            String dexPath, String librarySearchPath, ClassLoader parent,
            ClassLoader[] sharedLibraryLoaders) {
        this(dexPath, librarySearchPath, parent, sharedLibraryLoaders, null);
    }

    /**
     * Creates a {@code DelegateLastClassLoader} that operates on a given {@code dexPath}
     * and a {@code librarySearchPath}.
     *
     * The {@code dexPath} should consist of one or more of the following, separated by
     * {@code File.pathSeparator}, which is {@code ":"} on Android.
     *
     * <ul>
     * <li>JAR/ZIP/APK files, possibly containing a "classes.dex" file as well as arbitrary
     * resources.
     * <li>Raw ".dex" files (not inside a zip file).
     * </ul>
     *
     * @param dexPath the list of jar/apk files containing classes and resources, delimited by
     *                {@code File.pathSeparator}, which defaults to {@code ":"} on Android.
     * @param librarySearchPath the list of directories containing native libraries, delimited
     *                          by {@code File.pathSeparator}; may be {@code null}.
     * @param parent the parent class loader. May be {@code null} for the boot classloader.
     * @param sharedLibraryLoaders class loaders of Java shared libraries
     *                             used by this new class loader. The shared library loaders are
     *                             always checked before the {@code dexPath} when looking
     *                             up classes and resources.
     * @param sharedLibraryLoadersAfter class loaders of Java shared libraries
     *                             used by this new class loader. These shared library loaders are
     *                             always checked <b>after</b> the {@code dexPath} when looking
     *                             up classes and resources.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public DelegateLastClassLoader(
            String dexPath, String librarySearchPath, ClassLoader parent,
            ClassLoader[] sharedLibraryLoaders, ClassLoader[] sharedLibraryLoadersAfter) {
        super(dexPath, librarySearchPath, parent, sharedLibraryLoaders, sharedLibraryLoadersAfter);
        // Delegating is the default behavior.
        this.delegateResourceLoading = true;
    }

    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        // First, check whether the class has already been loaded. Return it if that's the
        // case.
        Class<?> cl = findLoadedClass(name);
        if (cl != null) {
            return cl;
        }

        // Next, check whether the class in question is present in the boot classpath.
        try {
            return Object.class.getClassLoader().loadClass(name);
        } catch (ClassNotFoundException ignored) {
        }

        // Next, check whether the class in question is present in the dexPath that this classloader
        // operates on, or its shared libraries.
        ClassNotFoundException fromSuper = null;
        try {
            return findClass(name);
        } catch (ClassNotFoundException ex) {
            fromSuper = ex;
        }

        // Finally, check whether the class in question is present in the parent classloader.
        try {
            return getParent().loadClass(name);
        } catch (ClassNotFoundException cnfe) {
            // The exception we're catching here is the CNFE thrown by the parent of this
            // classloader. However, we would like to throw a CNFE that provides details about
            // the class path / list of dex files associated with *this* classloader, so we choose
            // to throw the exception thrown from that lookup.
            throw fromSuper;
        }
    }

    @Override
    public URL getResource(String name) {
        // The lookup order we use here is the same as for classes.

        URL resource = Object.class.getClassLoader().getResource(name);
        if (resource != null) {
            return resource;
        }

        resource = findResource(name);
        if (resource != null) {
            return resource;
        }

        if (delegateResourceLoading) {
            final ClassLoader cl = getParent();
            return (cl == null) ? null : cl.getResource(name);
        }
        return null;
    }

    @Override
    public Enumeration<URL> getResources(String name) throws IOException {
        @SuppressWarnings("unchecked")
        final Enumeration<URL>[] resources = (Enumeration<URL>[]) new Enumeration<?>[] {
                Object.class.getClassLoader().getResources(name),
                findResources(name),
                (getParent() == null || !delegateResourceLoading)
                        ? null : getParent().getResources(name) };

        return new CompoundEnumeration<>(resources);
    }
}
