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

import static com.android.server.backup.RefactoredBackupManagerService.DEBUG;
import static com.android.server.backup.RefactoredBackupManagerService.TAG;

import android.content.Context;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.Session;
import android.content.pm.PackageInstaller.SessionParams;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.server.backup.FileMetadata;
import com.android.server.backup.restore.RestoreDeleteObserver;
import com.android.server.backup.restore.RestorePolicy;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;

/**
 * Utility methods used by {@link com.android.server.backup.restore.PerformAdbRestoreTask} and
 * {@link com.android.server.backup.restore.FullRestoreEngine}.
 */
public class RestoreUtils {
    /**
     * Reads apk contents from input stream and installs the apk.
     *
     * @param instream - input stream to read apk data from.
     * @param context - installing context
     * @param deleteObserver - {@link RestoreDeleteObserver} instance.
     * @param manifestSignatures - manifest signatures.
     * @param packagePolicies - package policies.
     * @param info - backup file info.
     * @param installerPackageName - package name of installer.
     * @param bytesReadListener - listener to be called for counting bytes read.
     * @return true if apk was successfully read and installed and false otherwise.
     */
    // TODO: Refactor to get rid of unneeded params.
    public static boolean installApk(InputStream instream, Context context,
            RestoreDeleteObserver deleteObserver,
            HashMap<String, Signature[]> manifestSignatures,
            HashMap<String, RestorePolicy> packagePolicies,
            FileMetadata info,
            String installerPackageName, BytesReadListener bytesReadListener) {
        boolean okay = true;

        if (DEBUG) {
            Slog.d(TAG, "Installing from backup: " + info.packageName);
        }

        try {
            LocalIntentReceiver receiver = new LocalIntentReceiver();
            PackageManager packageManager = context.getPackageManager();
            PackageInstaller installer = packageManager.getPackageInstaller();

            SessionParams params = new SessionParams(SessionParams.MODE_FULL_INSTALL);
            params.setInstallerPackageName(installerPackageName);
            int sessionId = installer.createSession(params);
            try {
                try (Session session = installer.openSession(sessionId)) {
                    try (OutputStream apkStream = session.openWrite(info.packageName, 0,
                            info.size)) {
                        byte[] buffer = new byte[32 * 1024];
                        long size = info.size;
                        while (size > 0) {
                            long toRead = (buffer.length < size) ? buffer.length : size;
                            int didRead = instream.read(buffer, 0, (int) toRead);
                            if (didRead >= 0) {
                                bytesReadListener.onBytesRead(didRead);
                            }
                            apkStream.write(buffer, 0, didRead);
                            size -= didRead;
                        }
                    }

                    // Installation is current disabled
                    session.abandon();
                    // session.commit(receiver.getIntentSender());
                }
            } catch (Exception t) {
                installer.abandonSession(sessionId);

                throw t;
            }

            // Installation is current disabled
            Intent result = null;
            // Intent result = receiver.getResult();

            // Installation is current disabled
            int status = PackageInstaller.STATUS_FAILURE;
            // int status = result.getIntExtra(PackageInstaller.EXTRA_STATUS,
            //        PackageInstaller.STATUS_FAILURE);

            if (status != PackageInstaller.STATUS_SUCCESS) {
                // The only time we continue to accept install of data even if the
                // apk install failed is if we had already determined that we could
                // accept the data regardless.
                if (packagePolicies.get(info.packageName) != RestorePolicy.ACCEPT) {
                    okay = false;
                }
            } else {
                // Okay, the install succeeded.  Make sure it was the right app.
                boolean uninstall = false;
                final String installedPackageName = result.getStringExtra(
                        PackageInstaller.EXTRA_PACKAGE_NAME);
                if (!installedPackageName.equals(info.packageName)) {
                    Slog.w(TAG, "Restore stream claimed to include apk for "
                            + info.packageName + " but apk was really "
                            + installedPackageName);
                    // delete the package we just put in place; it might be fraudulent
                    okay = false;
                    uninstall = true;
                } else {
                    try {
                        PackageInfo pkg = packageManager.getPackageInfo(
                                info.packageName,
                                PackageManager.GET_SIGNATURES);
                        if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP)
                                == 0) {
                            Slog.w(TAG, "Restore stream contains apk of package "
                                    + info.packageName
                                    + " but it disallows backup/restore");
                            okay = false;
                        } else {
                            // So far so good -- do the signatures match the manifest?
                            Signature[] sigs = manifestSignatures.get(info.packageName);
                            if (AppBackupUtils.signaturesMatch(sigs, pkg)) {
                                // If this is a system-uid app without a declared backup agent,
                                // don't restore any of the file data.
                                if ((pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID)
                                        && (pkg.applicationInfo.backupAgentName == null)) {
                                    Slog.w(TAG, "Installed app " + info.packageName
                                            + " has restricted uid and no agent");
                                    okay = false;
                                }
                            } else {
                                Slog.w(TAG, "Installed app " + info.packageName
                                        + " signatures do not match restore manifest");
                                okay = false;
                                uninstall = true;
                            }
                        }
                    } catch (PackageManager.NameNotFoundException e) {
                        Slog.w(TAG, "Install of package " + info.packageName
                                + " succeeded but now not found");
                        okay = false;
                    }
                }

                // If we're not okay at this point, we need to delete the package
                // that we just installed.
                if (uninstall) {
                    deleteObserver.reset();
                    packageManager.deletePackage(
                            installedPackageName,
                            deleteObserver, 0);
                    deleteObserver.waitForCompletion();
                }
            }
        } catch (IOException e) {
            Slog.e(TAG, "Unable to transcribe restored apk for install");
            okay = false;
        }

        return okay;
    }

    private static class LocalIntentReceiver {
        private final Object mLock = new Object();

        @GuardedBy("mLock")
        private Intent mResult = null;

        private IIntentSender.Stub mLocalSender = new IIntentSender.Stub() {
            @Override
            public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken,
                    IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
                synchronized (mLock) {
                    mResult = intent;
                    mLock.notifyAll();
                }
            }
        };

        public IntentSender getIntentSender() {
            return new IntentSender((IIntentSender) mLocalSender);
        }

        public Intent getResult() {
            synchronized (mLock) {
                while (mResult == null) {
                    try {
                        mLock.wait();
                    } catch (InterruptedException e) {
                        // ignored
                    }
                }

                return mResult;
            }
        }
    }
}
