/*
 * 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 com.android.server.backup.fullbackup;

import static com.android.server.backup.BackupManagerService.DEBUG;
import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
import static com.android.server.backup.BackupManagerService.TAG;
import static com.android.server.backup.UserBackupManagerService.BACKUP_MANIFEST_FILENAME;
import static com.android.server.backup.UserBackupManagerService.BACKUP_METADATA_FILENAME;
import static com.android.server.backup.UserBackupManagerService.OP_TYPE_BACKUP_WAIT;
import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;

import android.annotation.UserIdInt;
import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
import android.app.backup.BackupTransport;
import android.app.backup.FullBackupDataOutput;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.util.Slog;

import com.android.internal.util.Preconditions;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.UserBackupManagerService;
import com.android.server.backup.remote.RemoteCall;
import com.android.server.backup.utils.FullBackupUtils;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

/**
 * Core logic for performing one package's full backup, gathering the tarball from the application
 * and emitting it to the designated OutputStream.
 */
public class FullBackupEngine {
    private UserBackupManagerService backupManagerService;
    private OutputStream mOutput;
    private FullBackupPreflight mPreflightHook;
    private BackupRestoreTask mTimeoutMonitor;
    private IBackupAgent mAgent;
    private boolean mIncludeApks;
    private PackageInfo mPkg;
    private final long mQuota;
    private final int mOpToken;
    private final int mTransportFlags;
    private final BackupAgentTimeoutParameters mAgentTimeoutParameters;

    class FullBackupRunner implements Runnable {
        private final @UserIdInt int mUserId;
        private final PackageManager mPackageManager;
        private final PackageInfo mPackage;
        private final IBackupAgent mAgent;
        private final ParcelFileDescriptor mPipe;
        private final int mToken;
        private final boolean mIncludeApks;
        private final File mFilesDir;

        FullBackupRunner(
                UserBackupManagerService userBackupManagerService,
                PackageInfo packageInfo,
                IBackupAgent agent,
                ParcelFileDescriptor pipe,
                int token,
                boolean includeApks)
                throws IOException {
            mUserId = userBackupManagerService.getUserId();
            mPackageManager = backupManagerService.getPackageManager();
            mPackage = packageInfo;
            mAgent = agent;
            mPipe = ParcelFileDescriptor.dup(pipe.getFileDescriptor());
            mToken = token;
            mIncludeApks = includeApks;
            mFilesDir = userBackupManagerService.getDataDir();
        }

        @Override
        public void run() {
            try {
                FullBackupDataOutput output =
                        new FullBackupDataOutput(mPipe, /* quota */ -1, mTransportFlags);
                AppMetadataBackupWriter appMetadataBackupWriter =
                        new AppMetadataBackupWriter(output, mPackageManager);

                String packageName = mPackage.packageName;
                boolean isSharedStorage = SHARED_BACKUP_AGENT_PACKAGE.equals(packageName);
                boolean writeApk =
                        shouldWriteApk(mPackage.applicationInfo, mIncludeApks, isSharedStorage);

                if (!isSharedStorage) {
                    if (MORE_DEBUG) {
                        Slog.d(TAG, "Writing manifest for " + packageName);
                    }

                    File manifestFile = new File(mFilesDir, BACKUP_MANIFEST_FILENAME);
                    appMetadataBackupWriter.backupManifest(
                            mPackage, manifestFile, mFilesDir, writeApk);
                    manifestFile.delete();

                    // Write widget data.
                    byte[] widgetData =
                            AppWidgetBackupBridge.getWidgetState(packageName, mUserId);
                    if (widgetData != null && widgetData.length > 0) {
                        File metadataFile = new File(mFilesDir, BACKUP_METADATA_FILENAME);
                        appMetadataBackupWriter.backupWidget(
                                mPackage, metadataFile, mFilesDir, widgetData);
                        metadataFile.delete();
                    }
                }

                // TODO(b/113807190): Look into removing, only used for 'adb backup'.
                if (writeApk) {
                    appMetadataBackupWriter.backupApk(mPackage);
                    appMetadataBackupWriter.backupObb(mUserId, mPackage);
                }

                if (DEBUG) {
                    Slog.d(TAG, "Calling doFullBackup() on " + packageName);
                }

                long timeout =
                        isSharedStorage
                                ? mAgentTimeoutParameters.getSharedBackupAgentTimeoutMillis()
                                : mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis();
                backupManagerService.prepareOperationTimeout(
                        mToken,
                        timeout,
                        mTimeoutMonitor /* in parent class */,
                        OP_TYPE_BACKUP_WAIT);
                mAgent.doFullBackup(
                        mPipe,
                        mQuota,
                        mToken,
                        backupManagerService.getBackupManagerBinder(),
                        mTransportFlags);
            } catch (IOException e) {
                Slog.e(TAG, "Error running full backup for " + mPackage.packageName, e);
            } catch (RemoteException e) {
                Slog.e(
                        TAG,
                        "Remote agent vanished during full backup of " + mPackage.packageName,
                        e);
            } finally {
                try {
                    mPipe.close();
                } catch (IOException e) {
                }
            }
        }

        /**
         * Don't write apks for system-bundled apps that are not upgraded.
         */
        private boolean shouldWriteApk(
                ApplicationInfo applicationInfo, boolean includeApks, boolean isSharedStorage) {
            boolean isSystemApp = (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
            boolean isUpdatedSystemApp =
                    (applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
            return includeApks
                    && !isSharedStorage
                    && (!isSystemApp || isUpdatedSystemApp);
        }
    }

    public FullBackupEngine(
            UserBackupManagerService backupManagerService,
            OutputStream output,
            FullBackupPreflight preflightHook,
            PackageInfo pkg,
            boolean alsoApks,
            BackupRestoreTask timeoutMonitor,
            long quota,
            int opToken,
            int transportFlags) {
        this.backupManagerService = backupManagerService;
        mOutput = output;
        mPreflightHook = preflightHook;
        mPkg = pkg;
        mIncludeApks = alsoApks;
        mTimeoutMonitor = timeoutMonitor;
        mQuota = quota;
        mOpToken = opToken;
        mTransportFlags = transportFlags;
        mAgentTimeoutParameters =
                Preconditions.checkNotNull(
                        backupManagerService.getAgentTimeoutParameters(),
                        "Timeout parameters cannot be null");
    }

    public int preflightCheck() throws RemoteException {
        if (mPreflightHook == null) {
            if (MORE_DEBUG) {
                Slog.v(TAG, "No preflight check");
            }
            return BackupTransport.TRANSPORT_OK;
        }
        if (initializeAgent()) {
            int result = mPreflightHook.preflightFullBackup(mPkg, mAgent);
            if (MORE_DEBUG) {
                Slog.v(TAG, "preflight returned " + result);
            }
            return result;
        } else {
            Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
            return BackupTransport.AGENT_ERROR;
        }
    }

    public int backupOnePackage() throws RemoteException {
        int result = BackupTransport.AGENT_ERROR;

        if (initializeAgent()) {
            ParcelFileDescriptor[] pipes = null;
            try {
                pipes = ParcelFileDescriptor.createPipe();

                FullBackupRunner runner =
                        new FullBackupRunner(
                                backupManagerService,
                                mPkg,
                                mAgent,
                                pipes[1],
                                mOpToken,
                                mIncludeApks);
                pipes[1].close(); // the runner has dup'd it
                pipes[1] = null;
                Thread t = new Thread(runner, "app-data-runner");
                t.start();

                FullBackupUtils.routeSocketDataToOutput(pipes[0], mOutput);

                if (!backupManagerService.waitUntilOperationComplete(mOpToken)) {
                    Slog.e(TAG, "Full backup failed on package " + mPkg.packageName);
                } else {
                    if (MORE_DEBUG) {
                        Slog.d(TAG, "Full package backup success: " + mPkg.packageName);
                    }
                    result = BackupTransport.TRANSPORT_OK;
                }
            } catch (IOException e) {
                Slog.e(TAG, "Error backing up " + mPkg.packageName + ": " + e.getMessage());
                result = BackupTransport.AGENT_ERROR;
            } finally {
                try {
                    // flush after every package
                    mOutput.flush();
                    if (pipes != null) {
                        if (pipes[0] != null) {
                            pipes[0].close();
                        }
                        if (pipes[1] != null) {
                            pipes[1].close();
                        }
                    }
                } catch (IOException e) {
                    Slog.w(TAG, "Error bringing down backup stack");
                    result = BackupTransport.TRANSPORT_ERROR;
                }
            }
        } else {
            Slog.w(TAG, "Unable to bind to full agent for " + mPkg.packageName);
        }
        tearDown();
        return result;
    }

    public void sendQuotaExceeded(long backupDataBytes, long quotaBytes) {
        if (initializeAgent()) {
            try {
                RemoteCall.execute(
                        callback -> mAgent.doQuotaExceeded(backupDataBytes, quotaBytes, callback),
                        mAgentTimeoutParameters.getQuotaExceededTimeoutMillis());
            } catch (RemoteException e) {
                Slog.e(TAG, "Remote exception while telling agent about quota exceeded");
            }
        }
    }

    private boolean initializeAgent() {
        if (mAgent == null) {
            if (MORE_DEBUG) {
                Slog.d(TAG, "Binding to full backup agent : " + mPkg.packageName);
            }
            mAgent =
                    backupManagerService.bindToAgentSynchronous(
                            mPkg.applicationInfo, ApplicationThreadConstants.BACKUP_MODE_FULL);
        }
        return mAgent != null;
    }

    private void tearDown() {
        if (mPkg != null) {
            backupManagerService.tearDownAgentAndKill(mPkg.applicationInfo);
        }
    }
}
