/*
 * 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 dalvik.system;

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

import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import libcore.util.NonNull;
import libcore.util.Nullable;
import sun.misc.CompoundEnumeration;

/**
 * Base class for common functionality between various dex-based
 * {@link ClassLoader} implementations.
 */
public class BaseDexClassLoader extends ClassLoader {

    /**
     * Hook for customizing how dex files loads are reported.
     *
     * This enables the framework to monitor the use of dex files. The
     * goal is to simplify the mechanism for optimizing foreign dex files and
     * enable further optimizations of secondary dex files.
     *
     * The reporting happens only when new instances of BaseDexClassLoader
     * are constructed and will be active only after this field is set with
     * {@link BaseDexClassLoader#setReporter}.
     */
    /* @NonNull */ private static volatile Reporter reporter = null;

    @UnsupportedAppUsage
    private final DexPathList pathList;

    /**
     * Array of ClassLoaders that can be used to load classes and resources that the code in
     * {@code pathList} may depend on. This is used to implement Android's
     * <a href=https://developer.android.com/guide/topics/manifest/uses-library-element>
     * shared libraries</a> feature.
     * <p>The shared library loaders are always checked before the {@code pathList} when looking
     * up classes and resources.
     *
     * <p>{@code null} if the class loader has no shared library.
     *
     * @hide
     */
    protected final ClassLoader[] sharedLibraryLoaders;

    /**
     * Array of ClassLoaders identical to {@code sharedLibraryLoaders} except that these library
     * loaders are always checked after the {@code pathList} when looking up classes and resources.
     *
     * The placement of a library into this group is done by the OEM and cannot be configured by
     * an App.
     *
     * <p>{@code null} if the class loader has no shared library.
     *
     * @hide
     */
    protected final ClassLoader[] sharedLibraryLoadersAfter;

    /**
     * Constructs an instance.
     * Note that all the *.jar and *.apk files from {@code dexPath} might be
     * first extracted in-memory before the code is loaded. This can be avoided
     * by passing raw dex files (*.dex) in the {@code dexPath}.
     *
     * @param dexPath the list of jar/apk files containing classes and
     * resources, delimited by {@code File.pathSeparator}, which
     * defaults to {@code ":"} on Android.
     * @param optimizedDirectory this parameter is deprecated and has no effect since API level 26.
     * @param librarySearchPath the list of directories containing native
     * libraries, delimited by {@code File.pathSeparator}; may be
     * {@code null}
     * @param parent the parent class loader
     */
    public BaseDexClassLoader(String dexPath, File optimizedDirectory,
            String librarySearchPath, ClassLoader parent) {
        this(dexPath, librarySearchPath, parent, null, null, false);
    }

    /**
     * @hide
     */
    @UnsupportedAppUsage
    public BaseDexClassLoader(String dexPath, File optimizedDirectory,
            String librarySearchPath, ClassLoader parent, boolean isTrusted) {
        this(dexPath, librarySearchPath, parent, null, null, isTrusted);
    }

    /**
     * @hide
     */
    public BaseDexClassLoader(String dexPath,
            String librarySearchPath, ClassLoader parent, ClassLoader[] libraries) {
        this(dexPath, librarySearchPath, parent, libraries, null, false);
    }

    /**
     * @hide
     */
    public BaseDexClassLoader(String dexPath, String librarySearchPath,
            ClassLoader parent, ClassLoader[] libraries, ClassLoader[] librariesAfter) {
        this(dexPath, librarySearchPath, parent, libraries, librariesAfter, false);
    }


    /**
     * BaseDexClassLoader implements the Android
     * <a href=https://developer.android.com/guide/topics/manifest/uses-library-element>
     * shared libraries</a> feature by changing the typical parent delegation mechanism
     * of class loaders.
     * <p> Each shared library is associated with its own class loader, which is added to a list of
     * class loaders this BaseDexClassLoader tries to load from in order, immediately checking
     * after the parent.
     * The shared library loaders are always checked before the {@code pathList} when looking
     * up classes and resources.
     * <p>
     * The shared library loaders defined in sharedLibraryLoadersAfter are always checked
     * <b>after</b> the {@code pathList}
     *
     * @hide
     */
    public BaseDexClassLoader(String dexPath,
            String librarySearchPath, ClassLoader parent, ClassLoader[] sharedLibraryLoaders,
            ClassLoader[] sharedLibraryLoadersAfter,
            boolean isTrusted) {
        super(parent);
        // Setup shared libraries before creating the path list. ART relies on the class loader
        // hierarchy being finalized before loading dex files.
        this.sharedLibraryLoaders = sharedLibraryLoaders == null
                ? null
                : Arrays.copyOf(sharedLibraryLoaders, sharedLibraryLoaders.length);
        this.pathList = new DexPathList(this, dexPath, librarySearchPath, null, isTrusted);

        this.sharedLibraryLoadersAfter = sharedLibraryLoadersAfter == null
                ? null
                : Arrays.copyOf(sharedLibraryLoadersAfter, sharedLibraryLoadersAfter.length);
        // Run background verification after having set 'pathList'.
        this.pathList.maybeRunBackgroundVerification(this);

        reportClassLoaderChain();
    }

    /**
     * Reports the current class loader chain to the registered {@code reporter}.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public void reportClassLoaderChain() {
        if (reporter == null) {
            return;
        }

        String[] classPathAndClassLoaderContexts = computeClassLoaderContextsNative();
        if (classPathAndClassLoaderContexts.length == 0) {
            return;
        }
        Map<String, String> dexFileMapping =
                new HashMap<>(classPathAndClassLoaderContexts.length / 2);
        for (int i = 0; i < classPathAndClassLoaderContexts.length; i += 2) {
            dexFileMapping.put(classPathAndClassLoaderContexts[i],
                    classPathAndClassLoaderContexts[i + 1]);
        }
        reporter.report(Collections.unmodifiableMap(dexFileMapping));
    }

    /**
     * Computes the classloader contexts for each classpath entry in {@code pathList.getDexPaths()}.
     *
     * Note that this method is not thread safe, i.e. it is the responsibility of the caller to
     * ensure that {@code pathList.getDexPaths()} is not modified concurrently with this method
     * being called.
     *
     * @return A non-null array of non-null strings of length
     *   {@code 2 * pathList.getDexPaths().size()}. Every even index (0 is even here) is a dex file
     *   path and every odd entry is the class loader context used to load the previously listed dex
     *   file. E.g. a result might be {@code { "foo.dex", "PCL[]", "bar.dex", "PCL[foo.dex]" } }.
     */
    private native String[] computeClassLoaderContextsNative();

    /**
     * Constructs an instance.
     *
     * dexFile must be an in-memory representation of a full dexFile.
     *
     * @param dexFiles the array of in-memory dex files containing classes.
     * @param librarySearchPath the list of directories containing native
     *   libraries, delimited by {@code File.pathSeparator}; may be {@code null}
     * @param parent the parent class loader
     *
     * @hide
     */
    public BaseDexClassLoader(ByteBuffer[] dexFiles, String librarySearchPath, ClassLoader parent) {
        super(parent);
        this.sharedLibraryLoaders = null;
        this.sharedLibraryLoadersAfter = null;
        this.pathList = new DexPathList(this, librarySearchPath);
        this.pathList.initByteBufferDexPath(dexFiles);
        // Run background verification after having set 'pathList'.
        this.pathList.maybeRunBackgroundVerification(this);
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        // First, check whether the class is present in our shared libraries.
        if (sharedLibraryLoaders != null) {
            for (ClassLoader loader : sharedLibraryLoaders) {
                try {
                    return loader.loadClass(name);
                } catch (ClassNotFoundException ignored) {
                }
            }
        }
        // Check whether the class in question is present in the dexPath that
        // this classloader operates on.
        List<Throwable> suppressedExceptions = new ArrayList<Throwable>();
        Class c = pathList.findClass(name, suppressedExceptions);
        if (c != null) {
            return c;
        }
        // Now, check whether the class is present in the "after" shared libraries.
        if (sharedLibraryLoadersAfter != null) {
            for (ClassLoader loader : sharedLibraryLoadersAfter) {
                try {
                    return loader.loadClass(name);
                } catch (ClassNotFoundException ignored) {
                }
            }
        }
        if (c == null) {
            ClassNotFoundException cnfe = new ClassNotFoundException(
                    "Didn't find class \"" + name + "\" on path: " + pathList);
            for (Throwable t : suppressedExceptions) {
                cnfe.addSuppressed(t);
            }
            throw cnfe;
        }
        return c;
    }

    /**
     * Adds a new dex path to path list.
     *
     * @param dexPath dex path to add to path list
     *
     * @hide
     */
    @UnsupportedAppUsage
    @SystemApi(client = MODULE_LIBRARIES)
    public void addDexPath(@Nullable String dexPath) {
        addDexPath(dexPath, false /*isTrusted*/);
    }

    /**
     * @hide
     */
    @UnsupportedAppUsage
    public void addDexPath(String dexPath, boolean isTrusted) {
        pathList.addDexPath(dexPath, null /*optimizedDirectory*/, isTrusted);
    }

    /**
     * Adds additional native paths for consideration in subsequent calls to
     * {@link #findLibrary(String)}.
     *
     * @param libPaths collection of paths to be added to path list
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public void addNativePath(@NonNull Collection<String> libPaths) {
        pathList.addNativePath(libPaths);
    }

    @Override
    protected URL findResource(String name) {
        if (sharedLibraryLoaders != null) {
            for (ClassLoader loader : sharedLibraryLoaders) {
                URL url = loader.getResource(name);
                if (url != null) {
                    return url;
                }
            }
        }
        URL url = pathList.findResource(name);
        if (url != null) {
            return url;
        }
        if (sharedLibraryLoadersAfter != null) {
            for (ClassLoader loader : sharedLibraryLoadersAfter) {
                URL url2 = loader.getResource(name);
                if (url2 != null) {
                    return url2;
                }
            }
        }
        return null;
    }

    @Override
    protected Enumeration<URL> findResources(String name) {
        Enumeration<URL> myResources = pathList.findResources(name);
        if (sharedLibraryLoaders == null && sharedLibraryLoadersAfter == null) {
          return myResources;
        }

        int sharedLibraryLoadersCount =
                (sharedLibraryLoaders != null) ? sharedLibraryLoaders.length : 0;
        int sharedLibraryLoadersAfterCount =
                (sharedLibraryLoadersAfter != null) ? sharedLibraryLoadersAfter.length : 0;

        Enumeration<URL>[] tmp =
                (Enumeration<URL>[]) new Enumeration<?>[sharedLibraryLoadersCount +
                        sharedLibraryLoadersAfterCount
                        + 1];
        // First add sharedLibrary resources.
        // This will add duplicate resources if a shared library is loaded twice, but that's ok
        // as we don't guarantee uniqueness.
        int i = 0;
        for (; i < sharedLibraryLoadersCount; i++) {
            try {
                tmp[i] = sharedLibraryLoaders[i].getResources(name);
            } catch (IOException e) {
                // Ignore.
            }
        }
        // Then add resource from this dex path.
        tmp[i++] = myResources;

        // Finally add resources from shared libraries that are to be loaded after.
        for (int j = 0; j < sharedLibraryLoadersAfterCount; i++, j++) {
            try {
                tmp[i] = sharedLibraryLoadersAfter[j].getResources(name);
            } catch (IOException e) {
                // Ignore.
            }
        }
        return new CompoundEnumeration<>(tmp);
    }

    @Override
    public String findLibrary(String name) {
        return pathList.findLibrary(name);
    }

    /**
     * Returns package information for the given package.
     * Unfortunately, instances of this class don't really have this
     * information, and as a non-secure {@code ClassLoader}, it isn't
     * even required to, according to the spec. Yet, we want to
     * provide it, in order to make all those hopeful callers of
     * {@code myClass.getPackage().getName()} happy. Thus we construct
     * a {@code Package} object the first time it is being requested
     * and fill most of the fields with fake values. The {@code
     * Package} object is then put into the {@code ClassLoader}'s
     * package cache, so we see the same one next time. We don't
     * create {@code Package} objects for {@code null} arguments or
     * for the default package.
     *
     * <p>There is a limited chance that we end up with multiple
     * {@code Package} objects representing the same package: It can
     * happen when when a package is scattered across different JAR
     * files which were loaded by different {@code ClassLoader}
     * instances. This is rather unlikely, and given that this whole
     * thing is more or less a workaround, probably not worth the
     * effort to address.
     *
     * @param name the name of the class
     * @return the package information for the class, or {@code null}
     * if there is no package information available for it
     *
     * @deprecated See {@link ClassLoader#getPackage(String)}
     */
    @Deprecated
    @Override
    protected synchronized Package getPackage(String name) {
        if (name != null && !name.isEmpty()) {
            Package pack = super.getPackage(name);

            if (pack == null) {
                pack = definePackage(name, "Unknown", "0.0", "Unknown",
                        "Unknown", "0.0", "Unknown", null);
            }

            return pack;
        }

        return null;
    }

    /**
     * Returns colon-separated set of directories where libraries should be
     * searched for first, before the standard set of directories.
     *
     * @return colon-separated set of search directories
     *
     * @hide
     */
    @UnsupportedAppUsage
    @SystemApi(client = MODULE_LIBRARIES)
    public @NonNull String getLdLibraryPath() {
        StringBuilder result = new StringBuilder();
        for (File directory : pathList.getNativeLibraryDirectories()) {
            if (result.length() > 0) {
                result.append(':');
            }
            result.append(directory);
        }

        return result.toString();
    }

    @Override public String toString() {
        return getClass().getName() + "[" + pathList + "]";
    }

    /**
     * Sets the reporter for dex load notifications.
     * Once set, all new instances of BaseDexClassLoader will report upon
     * constructions the loaded dex files.
     *
     * @param newReporter the new Reporter. Setting {@code null} will cancel reporting.
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public static void setReporter(@Nullable Reporter newReporter) {
        reporter = newReporter;
    }

    /**
     * @hide
     */
    public static Reporter getReporter() {
        return reporter;
    }

    /**
     * Reports the construction of a {@link BaseDexClassLoader} and provides opaque
     * information about the class loader chain.
     *
     * @hide
     */
    @SystemApi(client = MODULE_LIBRARIES)
    public interface Reporter {
        /**
         * Reports the construction of a BaseDexClassLoader and provides opaque information about
         * the class loader chain. For example, if the childmost ClassLoader in the chain:
         * {@quote BaseDexClassLoader { foo.dex } -> BaseDexClassLoader { base.apk }
         *    -> BootClassLoader } was just initialized then the load of {@code "foo.dex"} would be
         * reported with a classLoaderContext of {@code "PCL[];PCL[base.apk]"}.
         *
         * @param contextsMap A map from dex file paths to the class loader context used to load
         *     each dex file.
         *
         * @hide
         */
        @SystemApi(client = MODULE_LIBRARIES)
        void report(@NonNull Map<String, String> contextsMap);
    }
}
