package com.android.server.backup;

import static android.os.ParcelFileDescriptor.MODE_CREATE;
import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
import static android.os.ParcelFileDescriptor.MODE_TRUNCATE;
import static com.android.server.backup.RefactoredBackupManagerService.OP_TYPE_BACKUP_WAIT;
import static com.android.server.backup.RefactoredBackupManagerService.TIMEOUT_BACKUP_INTERVAL;

import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
import android.app.backup.FullBackup;
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.os.SELinux;
import android.util.Slog;

import com.android.server.backup.utils.FullBackupUtils;

import libcore.io.IoUtils;

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

/**
 * Used by BackupManagerService to perform adb backup for key-value packages. At the moment this
 * class resembles what is done in the standard key-value code paths in BackupManagerService, and
 * should be unified later.
 *
 * TODO: We should create unified backup/restore engines that can be used for both transport and
 * adb backup/restore, and for fullbackup and key-value backup.
 */
public class KeyValueAdbBackupEngine {
    private static final String TAG = "KeyValueAdbBackupEngine";
    private static final boolean DEBUG = false;

    private static final String BACKUP_KEY_VALUE_DIRECTORY_NAME = "key_value_dir";
    private static final String BACKUP_KEY_VALUE_BLANK_STATE_FILENAME = "blank_state";
    private static final String BACKUP_KEY_VALUE_BACKUP_DATA_FILENAME_SUFFIX = ".data";
    private static final String BACKUP_KEY_VALUE_NEW_STATE_FILENAME_SUFFIX = ".new";

    private BackupManagerServiceInterface mBackupManagerService;
    private final PackageManager mPackageManager;
    private final OutputStream mOutput;
    private final PackageInfo mCurrentPackage;
    private final File mDataDir;
    private final File mStateDir;
    private final File mBlankStateName;
    private final File mBackupDataName;
    private final File mNewStateName;
    private final File mManifestFile;
    private ParcelFileDescriptor mSavedState;
    private ParcelFileDescriptor mBackupData;
    private ParcelFileDescriptor mNewState;

    public KeyValueAdbBackupEngine(OutputStream output, PackageInfo packageInfo,
            BackupManagerServiceInterface backupManagerService, PackageManager packageManager,
            File baseStateDir, File dataDir) {
        mOutput = output;
        mCurrentPackage = packageInfo;
        mBackupManagerService = backupManagerService;
        mPackageManager = packageManager;

        mDataDir = dataDir;
        mStateDir = new File(baseStateDir, BACKUP_KEY_VALUE_DIRECTORY_NAME);
        mStateDir.mkdirs();

        String pkg = mCurrentPackage.packageName;

        mBlankStateName = new File(mStateDir, BACKUP_KEY_VALUE_BLANK_STATE_FILENAME);
        mBackupDataName = new File(mDataDir,
                pkg + BACKUP_KEY_VALUE_BACKUP_DATA_FILENAME_SUFFIX);
        mNewStateName = new File(mStateDir,
                pkg + BACKUP_KEY_VALUE_NEW_STATE_FILENAME_SUFFIX);

        mManifestFile = new File(mDataDir, RefactoredBackupManagerService.BACKUP_MANIFEST_FILENAME);
    }

    public void backupOnePackage() throws IOException {
        ApplicationInfo targetApp = mCurrentPackage.applicationInfo;

        try {
            prepareBackupFiles(mCurrentPackage.packageName);

            IBackupAgent agent = bindToAgent(targetApp);

            if (agent == null) {
                // We failed binding to the agent, so ignore this package
                Slog.e(TAG, "Failed binding to BackupAgent for package "
                        + mCurrentPackage.packageName);
                return;
            }

            // We are bound to agent, initiate backup.
            if (!invokeAgentForAdbBackup(mCurrentPackage.packageName, agent)) {
                // Backup failed, skip package.
                Slog.e(TAG, "Backup Failed for package " + mCurrentPackage.packageName);
                return;
            }

            // Backup finished successfully. Copy the backup data to the output stream.
            writeBackupData();
        } catch (FileNotFoundException e) {
            Slog.e(TAG, "Failed creating files for package " + mCurrentPackage.packageName
                    + " will ignore package. " + e);
        } finally {
            // We are either done, failed or have timed out, so do cleanup and kill the agent.
            cleanup();
        }
    }

    private void  prepareBackupFiles(String packageName) throws FileNotFoundException {

        // We pass a blank state to make sure we are getting the complete backup, not just an
        // increment
        mSavedState = ParcelFileDescriptor.open(mBlankStateName,
                MODE_READ_ONLY | MODE_CREATE);  // Make an empty file if necessary

        mBackupData = ParcelFileDescriptor.open(mBackupDataName,
                MODE_READ_WRITE | MODE_CREATE | MODE_TRUNCATE);

        if (!SELinux.restorecon(mBackupDataName)) {
            Slog.e(TAG, "SELinux restorecon failed on " + mBackupDataName);
        }

        mNewState = ParcelFileDescriptor.open(mNewStateName,
                MODE_READ_WRITE | MODE_CREATE | MODE_TRUNCATE);
    }

    private IBackupAgent bindToAgent(ApplicationInfo targetApp) {
        try {
            return mBackupManagerService.bindToAgentSynchronous(targetApp,
                    ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
        } catch (SecurityException e) {
            Slog.e(TAG, "error in binding to agent for package " + targetApp.packageName
                    + ". " + e);
            return null;
        }
    }

    // Return true on backup success, false otherwise
    private boolean invokeAgentForAdbBackup(String packageName, IBackupAgent agent) {
        int token = mBackupManagerService.generateRandomIntegerToken();
        try {
            mBackupManagerService.prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL, null,
                    OP_TYPE_BACKUP_WAIT);

            // Start backup and wait for BackupManagerService to get callback for success or timeout
            agent.doBackup(mSavedState, mBackupData, mNewState, Long.MAX_VALUE, token,
                    mBackupManagerService.getBackupManagerBinder());
            if (!mBackupManagerService.waitUntilOperationComplete(token)) {
                Slog.e(TAG, "Key-value backup failed on package " + packageName);
                return false;
            }
            if (DEBUG) {
                Slog.i(TAG, "Key-value backup success for package " + packageName);
            }
            return true;
        } catch (RemoteException e) {
            Slog.e(TAG, "Error invoking agent for backup on " + packageName + ". " + e);
            return false;
        }
    }

    class KeyValueAdbBackupDataCopier implements Runnable {
        private final PackageInfo mPackage;
        private final ParcelFileDescriptor mPipe;
        private final int mToken;

        KeyValueAdbBackupDataCopier(PackageInfo pack, ParcelFileDescriptor pipe,
                int token)
                throws IOException {
            mPackage = pack;
            mPipe = ParcelFileDescriptor.dup(pipe.getFileDescriptor());
            mToken = token;
        }

        @Override
        public void run() {
            try {
                FullBackupDataOutput output = new FullBackupDataOutput(mPipe);

                if (DEBUG) {
                    Slog.d(TAG, "Writing manifest for " + mPackage.packageName);
                }
                FullBackupUtils.writeAppManifest(
                        mPackage, mPackageManager, mManifestFile, false, false);
                FullBackup.backupToTar(mPackage.packageName, FullBackup.KEY_VALUE_DATA_TOKEN, null,
                        mDataDir.getAbsolutePath(),
                        mManifestFile.getAbsolutePath(),
                        output);
                mManifestFile.delete();

                if (DEBUG) {
                    Slog.d(TAG, "Writing key-value package payload" + mPackage.packageName);
                }
                FullBackup.backupToTar(mPackage.packageName, FullBackup.KEY_VALUE_DATA_TOKEN, null,
                        mDataDir.getAbsolutePath(),
                        mBackupDataName.getAbsolutePath(),
                        output);

                // Write EOD marker
                try {
                    FileOutputStream out = new FileOutputStream(mPipe.getFileDescriptor());
                    byte[] buf = new byte[4];
                    out.write(buf);
                } catch (IOException e) {
                    Slog.e(TAG, "Unable to finalize backup stream!");
                }

                try {
                    mBackupManagerService.getBackupManagerBinder().opComplete(mToken, 0);
                } catch (RemoteException e) {
                    // we'll time out anyway, so we're safe
                }

            } catch (IOException e) {
                Slog.e(TAG, "Error running full backup for " + mPackage.packageName + ". " + e);
            } finally {
                IoUtils.closeQuietly(mPipe);
            }
        }
    }

    private void writeBackupData() throws IOException {

        int token = mBackupManagerService.generateRandomIntegerToken();

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

            mBackupManagerService.prepareOperationTimeout(token, TIMEOUT_BACKUP_INTERVAL, null,
                    OP_TYPE_BACKUP_WAIT);

            // We will have to create a runnable that will read the manifest and backup data we
            // created, such that we can pipe the data into mOutput. The reason we do this is that
            // internally FullBackup.backupToTar is used, which will create the necessary file
            // header, but will also chunk the data. The method routeSocketDataToOutput in
            // BackupManagerService will dechunk the data, and append it to the TAR outputstream.
            KeyValueAdbBackupDataCopier runner = new KeyValueAdbBackupDataCopier(mCurrentPackage, pipes[1],
                    token);
            pipes[1].close();   // the runner has dup'd it
            pipes[1] = null;
            Thread t = new Thread(runner, "key-value-app-data-runner");
            t.start();

            // Now pull data from the app and stuff it into the output
            FullBackupUtils.routeSocketDataToOutput(pipes[0], mOutput);

            if (!mBackupManagerService.waitUntilOperationComplete(token)) {
                Slog.e(TAG, "Full backup failed on package " + mCurrentPackage.packageName);
            } else {
                if (DEBUG) {
                    Slog.d(TAG, "Full package backup success: " + mCurrentPackage.packageName);
                }
            }
        } catch (IOException e) {
            Slog.e(TAG, "Error backing up " + mCurrentPackage.packageName + ": " + e);
        } finally {
            // flush after every package
            mOutput.flush();
            if (pipes != null) {
                IoUtils.closeQuietly(pipes[0]);
                IoUtils.closeQuietly(pipes[1]);
            }
        }
    }

    private void cleanup() {
        mBackupManagerService.tearDownAgentAndKill(mCurrentPackage.applicationInfo);
        mBlankStateName.delete();
        mNewStateName.delete();
        mBackupDataName.delete();
    }
}
