/*
 * Copyright (C) 2019 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.os.incremental;

/**
 * Set up files and directories used in an installation session.
 * Currently only used by Incremental Installation.
 * For Incremental installation, the expected outcome of this function is:
 * 0) All the files are in defaultStorage
 * 1) All APK files are in the same directory, bound to mApkStorage, and bound to the
 * InstallerSession's stage dir. The files are linked from mApkStorage to defaultStorage.
 * 2) All lib files are in the sub directories as their names suggest, and in the same parent
 * directory as the APK files. The files are linked from mApkStorage to defaultStorage.
 * 3) OBB files are in another directory that is different from APK files and lib files, bound
 * to mObbStorage. The files are linked from mObbStorage to defaultStorage.
 *
 * @throws IllegalStateException the session is not an Incremental installation session.
 */

import static dalvik.system.VMRuntime.getInstructionSet;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.DataLoaderParams;
import android.content.pm.InstallationFile;
import android.os.IVold;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.ArraySet;
import android.util.Slog;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Random;

/**
 * This class manages storage instances used during a package installation session.
 * @hide
 */
public final class IncrementalFileStorages {
    private static final String TAG = "IncrementalFileStorages";
    private @Nullable IncrementalStorage mDefaultStorage;
    private @Nullable IncrementalStorage mApkStorage;
    private @Nullable IncrementalStorage mObbStorage;
    private @Nullable String mDefaultDir;
    private @Nullable String mObbDir;
    private @NonNull IncrementalManager mIncrementalManager;
    private @Nullable ArraySet<String> mLibDirs;
    private @NonNull String mPackageName;
    private @NonNull File mStageDir;

    /**
     * Set up files and directories used in an installation session.
     * Currently only used by Incremental Installation.
     * For Incremental installation, the expected outcome of this function is:
     * 0) All the files are in defaultStorage
     * 1) All APK files are in the same directory, bound to mApkStorage, and bound to the
     * InstallerSession's stage dir. The files are linked from mApkStorage to defaultStorage.
     * 2) All lib files are in the sub directories as their names suggest, and in the same parent
     * directory as the APK files. The files are linked from mApkStorage to defaultStorage.
     * 3) OBB files are in another directory that is different from APK files and lib files, bound
     * to mObbStorage. The files are linked from mObbStorage to defaultStorage.
     *
     * @throws IllegalStateException the session is not an Incremental installation session.
     */
    public IncrementalFileStorages(@NonNull String packageName,
            @NonNull File stageDir,
            @NonNull IncrementalManager incrementalManager,
            @NonNull DataLoaderParams dataLoaderParams) {
        mPackageName = packageName;
        mStageDir = stageDir;
        mIncrementalManager = incrementalManager;
        if (dataLoaderParams.getComponentName().getPackageName().equals("local")) {
            final String incrementalPath = dataLoaderParams.getArguments();
            mDefaultStorage = mIncrementalManager.openStorage(incrementalPath);
            mDefaultDir = incrementalPath;
            return;
        }
        mDefaultDir = getTempDir();
        if (mDefaultDir == null) {
            return;
        }
        mDefaultStorage = mIncrementalManager.createStorage(mDefaultDir,
                dataLoaderParams,
                IncrementalManager.CREATE_MODE_CREATE
                        | IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false);
    }

    /**
     * Adds a file into the installation session. Makes sure it will be placed inside
     * a proper storage instance, based on its file type.
     */
    public void addFile(@NonNull InstallationFile file) throws IOException {
        if (mDefaultStorage == null) {
            throw new IOException("Cannot add file because default storage does not exist");
        }
        if (file.getFileType() == InstallationFile.FILE_TYPE_APK) {
            addApkFile(file);
        } else if (file.getFileType() == InstallationFile.FILE_TYPE_OBB) {
            addObbFile(file);
        } else if (file.getFileType() == InstallationFile.FILE_TYPE_LIB) {
            addLibFile(file);
        } else {
            throw new IOException("Unknown file type: " + file.getFileType());
        }
    }

    private void addApkFile(@NonNull InstallationFile apk) throws IOException {
        // Create a storage for APK files and lib files
        final String stageDirPath = mStageDir.getAbsolutePath();
        if (mApkStorage == null) {
            mApkStorage = mIncrementalManager.createStorage(stageDirPath, mDefaultStorage,
                    IncrementalManager.CREATE_MODE_CREATE
                            | IncrementalManager.CREATE_MODE_TEMPORARY_BIND);
            mApkStorage.bind(stageDirPath);
        }

        if (!new File(mDefaultDir, apk.getName()).exists()) {
            mDefaultStorage.makeFile(apk.getName(), apk.getSize(), null,
                    apk.getMetadata(), 0, null, null, null);
        }
        // Assuming APK files are already named properly, e.g., "base.apk"
        mDefaultStorage.makeLink(apk.getName(), mApkStorage, apk.getName());
    }

    private void addLibFile(@NonNull InstallationFile lib) throws IOException {
        // TODO(b/136132412): remove this after we have incfs support for lib file mapping
        if (mApkStorage == null) {
            throw new IOException("Cannot add lib file without adding an apk file first");
        }
        if (mLibDirs == null) {
            mLibDirs = new ArraySet<>();
        }
        String current = "";
        final Path libDirPath = Paths.get(lib.getName()).getParent();
        final int numDirComponents = libDirPath.getNameCount();
        for (int i = 0; i < numDirComponents; i++) {
            String dirName = libDirPath.getName(i).toString();
            try {
                dirName = getInstructionSet(dirName);
            } catch (IllegalArgumentException ignored) {
            }
            current += dirName;
            if (!mLibDirs.contains(current)) {
                mDefaultStorage.makeDirectory(current);
                mApkStorage.makeDirectory(current);
                mLibDirs.add(current);
            }
            current += '/';
        }
        String libFilePath = current + Paths.get(lib.getName()).getFileName();
        mDefaultStorage.makeFile(libFilePath, lib.getSize(), null, lib.getMetadata(), 0, null, null,
                                 null);
        mDefaultStorage.makeLink(libFilePath, mApkStorage, libFilePath);
    }

    private void addObbFile(@NonNull InstallationFile obb) throws IOException {
        if (mObbStorage == null) {
            // Create a storage for OBB files
            mObbDir = getTempDir();
            if (mObbDir == null) {
                throw new IOException("Failed to create obb storage directory.");
            }
            mObbStorage = mIncrementalManager.createStorage(
                    mObbDir, mDefaultStorage,
                    IncrementalManager.CREATE_MODE_CREATE
                            | IncrementalManager.CREATE_MODE_TEMPORARY_BIND);
        }
        mDefaultStorage.makeFile(obb.getName(), obb.getSize(), null, obb.getMetadata(), 0, null,
                                 null, null);
        mDefaultStorage.makeLink(obb.getName(), mObbStorage, obb.getName());
    }

    private boolean hasObb() {
        return (mObbStorage != null && mObbDir != null);
    }

    /**
     * Starts loading data for default storage.
     * TODO(b/136132412): update the implementation with latest API design.
     */
    public boolean startLoading() {
        if (mDefaultStorage == null) {
            return false;
        }
        return mDefaultStorage.startLoading();
    }

    /**
     * Sets up obb storage directory and create bindings.
     */
    public void finishSetUp() {
        if (!hasObb()) {
            return;
        }
        final String obbDir = "/storage/emulated/0/Android/obb";
        final String packageObbDir = String.format("%s/%s", obbDir, mPackageName);
        final String packageObbDirRoot =
                String.format("/mnt/runtime/%s/emulated/0/Android/obb/", mPackageName);
        final String[] obbDirs = {
                packageObbDirRoot + "read",
                packageObbDirRoot + "write",
                packageObbDirRoot + "full",
                packageObbDirRoot + "default",
                String.format("/data/media/0/Android/obb/%s", mPackageName),
                packageObbDir,
        };
        try {
            Slog.i(TAG, "Creating obb directory '" + packageObbDir + "'");
            final IVold vold = IVold.Stub.asInterface(ServiceManager.getServiceOrThrow("vold"));
            vold.setupAppDir(packageObbDir, obbDir, Process.ROOT_UID);
            for (String d : obbDirs) {
                mObbStorage.bindPermanent(d);
            }
        } catch (ServiceManager.ServiceNotFoundException ex) {
            Slog.e(TAG, "vold service is not found.");
            cleanUp();
        } catch (IOException | RemoteException ex) {
            Slog.e(TAG, "Failed to create obb dir at: " + packageObbDir, ex);
            cleanUp();
        }
    }

    /**
     * Resets the states and unbinds storage instances for an installation session.
     * TODO(b/136132412): make sure unnecessary binds are removed but useful storages are kept
     */
    public void cleanUp() {
        if (mDefaultStorage != null && mDefaultDir != null) {
            try {
                mDefaultStorage.unBind(mDefaultDir);
            } catch (IOException ignored) {
            }
            mDefaultDir = null;
            mDefaultStorage = null;
        }
        if (mApkStorage != null && mStageDir != null) {
            try {
                mApkStorage.unBind(mStageDir.getAbsolutePath());
            } catch (IOException ignored) {
            }
            mApkStorage = null;
        }
        if (mObbStorage != null && mObbDir != null) {
            try {
                mObbStorage.unBind(mObbDir);
            } catch (IOException ignored) {
            }
            mObbDir = null;
            mObbStorage = null;
        }
    }

    private String getTempDir() {
        final String tmpDirRoot = "/data/incremental/tmp";
        final Random random = new Random();
        final Path tmpDir =
                Paths.get(tmpDirRoot, String.valueOf(random.nextInt(Integer.MAX_VALUE - 1)));
        try {
            Files.createDirectories(tmpDir);
        } catch (Exception ex) {
            Slog.e(TAG, "Failed to create dir", ex);
            return null;
        }
        return tmpDir.toAbsolutePath().toString();
    }
}
