/*
 * 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 android.content.res;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.om.OverlayableInfo;
import android.content.res.loader.AssetsProvider;
import android.content.res.loader.ResourcesProvider;

import com.android.internal.annotations.GuardedBy;

import java.io.FileDescriptor;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
 * The loaded, immutable, in-memory representation of an APK.
 *
 * The main implementation is native C++ and there is very little API surface exposed here. The APK
 * is mainly accessed via {@link AssetManager}.
 *
 * Since the ApkAssets instance is immutable, it can be reused and shared across AssetManagers,
 * making the creation of AssetManagers very cheap.
 * @hide
 */
public final class ApkAssets {

    /**
     * The apk assets contains framework resource values specified by the system.
     * This allows some functions to filter out this package when computing what
     * configurations/resources are available.
     */
    public static final int PROPERTY_SYSTEM = 1 << 0;

    /**
     * The apk assets is a shared library or was loaded as a shared library by force.
     * The package ids of dynamic apk assets are assigned at runtime instead of compile time.
     */
    public static final int PROPERTY_DYNAMIC = 1 << 1;

    /**
     * The apk assets has been loaded dynamically using a {@link ResourcesProvider}.
     * Loader apk assets overlay resources like RROs except they are not backed by an idmap.
     */
    public static final int PROPERTY_LOADER = 1 << 2;

    /**
     * The apk assets is a RRO.
     * An RRO overlays resource values of its target package.
     */
    private static final int PROPERTY_OVERLAY = 1 << 3;

    /** Flags that change the behavior of loaded apk assets. */
    @IntDef(prefix = { "PROPERTY_" }, value = {
            PROPERTY_SYSTEM,
            PROPERTY_DYNAMIC,
            PROPERTY_LOADER,
            PROPERTY_OVERLAY,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PropertyFlags {}

    /** The path used to load the apk assets represents an APK file. */
    private static final int FORMAT_APK = 0;

    /** The path used to load the apk assets represents an idmap file. */
    private static final int FORMAT_IDMAP = 1;

    /** The path used to load the apk assets represents an resources.arsc file. */
    private static final int FORMAT_ARSC = 2;

    /** the path used to load the apk assets represents a directory. */
    private static final int FORMAT_DIR = 3;

    // Format types that change how the apk assets are loaded.
    @IntDef(prefix = { "FORMAT_" }, value = {
            FORMAT_APK,
            FORMAT_IDMAP,
            FORMAT_ARSC,
            FORMAT_DIR
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface FormatType {}

    @GuardedBy("this")
    private final long mNativePtr;

    @Nullable
    @GuardedBy("this")
    private final StringBlock mStringBlock;

    @GuardedBy("this")
    private boolean mOpen = true;

    @PropertyFlags
    private final int mFlags;

    @Nullable
    private final AssetsProvider mAssets;

    /**
     * Creates a new ApkAssets instance from the given path on disk.
     *
     * @param path The path to an APK on disk.
     * @return a new instance of ApkAssets.
     * @throws IOException if a disk I/O error or parsing error occurred.
     */
    public static @NonNull ApkAssets loadFromPath(@NonNull String path) throws IOException {
        return loadFromPath(path, 0 /* flags */);
    }

    /**
     * Creates a new ApkAssets instance from the given path on disk.
     *
     * @param path The path to an APK on disk.
     * @param flags flags that change the behavior of loaded apk assets
     * @return a new instance of ApkAssets.
     * @throws IOException if a disk I/O error or parsing error occurred.
     */
    public static @NonNull ApkAssets loadFromPath(@NonNull String path, @PropertyFlags int flags)
            throws IOException {
        return new ApkAssets(FORMAT_APK, path, flags, null /* assets */);
    }

    /**
     * Creates a new ApkAssets instance from the given path on disk.
     *
     * @param path The path to an APK on disk.
     * @param flags flags that change the behavior of loaded apk assets
     * @param assets The assets provider that overrides the loading of file-based resources
     * @return a new instance of ApkAssets.
     * @throws IOException if a disk I/O error or parsing error occurred.
     */
    public static @NonNull ApkAssets loadFromPath(@NonNull String path, @PropertyFlags int flags,
            @Nullable AssetsProvider assets) throws IOException {
        return new ApkAssets(FORMAT_APK, path, flags, assets);
    }

    /**
     * Creates a new ApkAssets instance from the given file descriptor.
     *
     * Performs a dup of the underlying fd, so you must take care of still closing
     * the FileDescriptor yourself (and can do that whenever you want).
     *
     * @param fd The FileDescriptor of an open, readable APK.
     * @param friendlyName The friendly name used to identify this ApkAssets when logging.
     * @param flags flags that change the behavior of loaded apk assets
     * @param assets The assets provider that overrides the loading of file-based resources
     * @return a new instance of ApkAssets.
     * @throws IOException if a disk I/O error or parsing error occurred.
     */
    public static @NonNull ApkAssets loadFromFd(@NonNull FileDescriptor fd,
            @NonNull String friendlyName, @PropertyFlags int flags,
            @Nullable AssetsProvider assets) throws IOException {
        return new ApkAssets(FORMAT_APK, fd, friendlyName, flags, assets);
    }

    /**
     * Creates a new ApkAssets instance from the given file descriptor.
     *
     * Performs a dup of the underlying fd, so you must take care of still closing
     * the FileDescriptor yourself (and can do that whenever you want).
     *
     * @param fd The FileDescriptor of an open, readable APK.
     * @param friendlyName The friendly name used to identify this ApkAssets when logging.
     * @param offset The location within the file that the apk starts. This must be 0 if length is
     *               {@link AssetFileDescriptor#UNKNOWN_LENGTH}.
     * @param length The number of bytes of the apk, or {@link AssetFileDescriptor#UNKNOWN_LENGTH}
     *               if it extends to the end of the file.
     * @param flags flags that change the behavior of loaded apk assets
     * @param assets The assets provider that overrides the loading of file-based resources
     * @return a new instance of ApkAssets.
     * @throws IOException if a disk I/O error or parsing error occurred.
     */
    public static @NonNull ApkAssets loadFromFd(@NonNull FileDescriptor fd,
            @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags,
            @Nullable AssetsProvider assets)
            throws IOException {
        return new ApkAssets(FORMAT_APK, fd, friendlyName, offset, length, flags, assets);
    }

    /**
     * Creates a new ApkAssets instance from the IDMAP at idmapPath. The overlay APK path
     * is encoded within the IDMAP.
     *
     * @param idmapPath Path to the IDMAP of an overlay APK.
     * @param flags flags that change the behavior of loaded apk assets
     * @return a new instance of ApkAssets.
     * @throws IOException if a disk I/O error or parsing error occurred.
     */
    public static @NonNull ApkAssets loadOverlayFromPath(@NonNull String idmapPath,
            @PropertyFlags int flags) throws IOException {
        return new ApkAssets(FORMAT_IDMAP, idmapPath, flags, null /* assets */);
    }

    /**
     * Creates a new ApkAssets instance from the given file descriptor representing a resources.arsc
     * for use with a {@link ResourcesProvider}.
     *
     * Performs a dup of the underlying fd, so you must take care of still closing
     * the FileDescriptor yourself (and can do that whenever you want).
     *
     * @param fd The FileDescriptor of an open, readable resources.arsc.
     * @param friendlyName The friendly name used to identify this ApkAssets when logging.
     * @param flags flags that change the behavior of loaded apk assets
     * @param assets The assets provider that overrides the loading of file-based resources
     * @return a new instance of ApkAssets.
     * @throws IOException if a disk I/O error or parsing error occurred.
     */
    public static @NonNull ApkAssets loadTableFromFd(@NonNull FileDescriptor fd,
            @NonNull String friendlyName, @PropertyFlags int flags,
            @Nullable AssetsProvider assets) throws IOException {
        return new ApkAssets(FORMAT_ARSC, fd, friendlyName, flags, assets);
    }

    /**
     * Creates a new ApkAssets instance from the given file descriptor representing a resources.arsc
     * for use with a {@link ResourcesProvider}.
     *
     * Performs a dup of the underlying fd, so you must take care of still closing
     * the FileDescriptor yourself (and can do that whenever you want).
     *
     * @param fd The FileDescriptor of an open, readable resources.arsc.
     * @param friendlyName The friendly name used to identify this ApkAssets when logging.
     * @param offset The location within the file that the table starts. This must be 0 if length is
     *               {@link AssetFileDescriptor#UNKNOWN_LENGTH}.
     * @param length The number of bytes of the table, or {@link AssetFileDescriptor#UNKNOWN_LENGTH}
     *               if it extends to the end of the file.
     * @param flags flags that change the behavior of loaded apk assets
     * @param assets The assets provider that overrides the loading of file-based resources
     * @return a new instance of ApkAssets.
     * @throws IOException if a disk I/O error or parsing error occurred.
     */
    public static @NonNull ApkAssets loadTableFromFd(@NonNull FileDescriptor fd,
            @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags,
            @Nullable AssetsProvider assets) throws IOException {
        return new ApkAssets(FORMAT_ARSC, fd, friendlyName, offset, length, flags, assets);
    }

    /**
     * Creates a new ApkAssets instance from the given directory path. The directory should have the
     * file structure of an APK.
     *
     * @param path The path to a directory on disk.
     * @param flags flags that change the behavior of loaded apk assets
     * @param assets The assets provider that overrides the loading of file-based resources
     * @return a new instance of ApkAssets.
     * @throws IOException if a disk I/O error or parsing error occurred.
     */
    public static @NonNull ApkAssets loadFromDir(@NonNull String path,
            @PropertyFlags int flags, @Nullable AssetsProvider assets) throws IOException {
        return new ApkAssets(FORMAT_DIR, path, flags, assets);
    }

    /**
     * Generates an entirely empty ApkAssets. Needed because the ApkAssets instance and presence
     * is required for a lot of APIs, and it's easier to have a non-null reference rather than
     * tracking a separate identifier.
     *
     * @param flags flags that change the behavior of loaded apk assets
     * @param assets The assets provider that overrides the loading of file-based resources
     */
    @NonNull
    public static ApkAssets loadEmptyForLoader(@PropertyFlags int flags,
            @Nullable AssetsProvider assets) {
        return new ApkAssets(flags, assets);
    }

    private ApkAssets(@FormatType int format, @NonNull String path, @PropertyFlags int flags,
            @Nullable AssetsProvider assets) throws IOException {
        Objects.requireNonNull(path, "path");
        mFlags = flags;
        mNativePtr = nativeLoad(format, path, flags, assets);
        mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/);
        mAssets = assets;
    }

    private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd,
            @NonNull String friendlyName, @PropertyFlags int flags, @Nullable AssetsProvider assets)
            throws IOException {
        Objects.requireNonNull(fd, "fd");
        Objects.requireNonNull(friendlyName, "friendlyName");
        mFlags = flags;
        mNativePtr = nativeLoadFd(format, fd, friendlyName, flags, assets);
        mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/);
        mAssets = assets;
    }

    private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd,
            @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags,
            @Nullable AssetsProvider assets) throws IOException {
        Objects.requireNonNull(fd, "fd");
        Objects.requireNonNull(friendlyName, "friendlyName");
        mFlags = flags;
        mNativePtr = nativeLoadFdOffsets(format, fd, friendlyName, offset, length, flags, assets);
        mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/);
        mAssets = assets;
    }

    private ApkAssets(@PropertyFlags int flags, @Nullable AssetsProvider assets) {
        mFlags = flags;
        mNativePtr = nativeLoadEmpty(flags, assets);
        mStringBlock = null;
        mAssets = assets;
    }

    @UnsupportedAppUsage
    public @NonNull String getAssetPath() {
        synchronized (this) {
            return nativeGetAssetPath(mNativePtr);
        }
    }

    CharSequence getStringFromPool(int idx) {
        if (mStringBlock == null) {
            return null;
        }

        synchronized (this) {
            return mStringBlock.get(idx);
        }
    }

    /** Returns whether this apk assets was loaded using a {@link ResourcesProvider}. */
    public boolean isForLoader() {
        return (mFlags & PROPERTY_LOADER) != 0;
    }

    /**
     * Returns the assets provider that overrides the loading of assets present in this apk assets.
     */
    @Nullable
    public AssetsProvider getAssetsProvider() {
        return mAssets;
    }

    /**
     * Retrieve a parser for a compiled XML file. This is associated with a single APK and
     * <em>NOT</em> a full AssetManager. This means that shared-library references will not be
     * dynamically assigned runtime package IDs.
     *
     * @param fileName The path to the file within the APK.
     * @return An XmlResourceParser.
     * @throws IOException if the file was not found or an error occurred retrieving it.
     */
    public @NonNull XmlResourceParser openXml(@NonNull String fileName) throws IOException {
        Objects.requireNonNull(fileName, "fileName");
        synchronized (this) {
            long nativeXmlPtr = nativeOpenXml(mNativePtr, fileName);
            try (XmlBlock block = new XmlBlock(null, nativeXmlPtr)) {
                XmlResourceParser parser = block.newParser();
                // If nativeOpenXml doesn't throw, it will always return a valid native pointer,
                // which makes newParser always return non-null. But let's be paranoid.
                if (parser == null) {
                    throw new AssertionError("block.newParser() returned a null parser");
                }
                return parser;
            }
        }
    }

    /** @hide */
    @Nullable
    public OverlayableInfo getOverlayableInfo(String overlayableName) throws IOException {
        return nativeGetOverlayableInfo(mNativePtr, overlayableName);
    }

    /** @hide */
    public boolean definesOverlayable() throws IOException {
        return nativeDefinesOverlayable(mNativePtr);
    }

    /**
     * Returns false if the underlying APK was changed since this ApkAssets was loaded.
     */
    public boolean isUpToDate() {
        synchronized (this) {
            return nativeIsUpToDate(mNativePtr);
        }
    }

    @Override
    public String toString() {
        return "ApkAssets{path=" + getAssetPath() + "}";
    }

    @Override
    protected void finalize() throws Throwable {
        close();
    }

    /**
     * Closes this class and the contained {@link #mStringBlock}.
     */
    public void close() {
        synchronized (this) {
            if (mOpen) {
                mOpen = false;
                if (mStringBlock != null) {
                    mStringBlock.close();
                }
                nativeDestroy(mNativePtr);
            }
        }
    }

    private static native long nativeLoad(@FormatType int format, @NonNull String path,
            @PropertyFlags int flags, @Nullable AssetsProvider asset) throws IOException;
    private static native long nativeLoadEmpty(@PropertyFlags int flags,
            @Nullable AssetsProvider asset);
    private static native long nativeLoadFd(@FormatType int format, @NonNull FileDescriptor fd,
            @NonNull String friendlyName, @PropertyFlags int flags,
            @Nullable AssetsProvider asset) throws IOException;
    private static native long nativeLoadFdOffsets(@FormatType int format,
            @NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length,
            @PropertyFlags int flags, @Nullable AssetsProvider asset) throws IOException;
    private static native void nativeDestroy(long ptr);
    private static native @NonNull String nativeGetAssetPath(long ptr);
    private static native long nativeGetStringBlock(long ptr);
    private static native boolean nativeIsUpToDate(long ptr);
    private static native long nativeOpenXml(long ptr, @NonNull String fileName) throws IOException;
    private static native @Nullable OverlayableInfo nativeGetOverlayableInfo(long ptr,
            String overlayableName) throws IOException;
    private static native boolean nativeDefinesOverlayable(long ptr) throws IOException;
}
