/*
 * Copyright (C) 2016 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;

import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.content.Context;
import android.net.Uri;
import android.util.Slog;

import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;

/**
 * Class to take an incident report.
 *
 * @hide
 */
@SystemApi
@TestApi
@SystemService(Context.INCIDENT_SERVICE)
public class IncidentManager {
    private static final String TAG = "IncidentManager";

    /**
     * Authority for pending report id urls.
     *
     * @hide
     */
    public static final String URI_SCHEME = "content";

    /**
     * Authority for pending report id urls.
     *
     * @hide
     */
    public static final String URI_AUTHORITY = "android.os.IncidentManager";

    /**
     * Authority for pending report id urls.
     *
     * @hide
     */
    public static final String URI_PATH = "/pending";

    /**
     * Query parameter for the uris for the pending report id.
     *
     * @hide
     */
    public static final String URI_PARAM_ID = "id";

    /**
     * Query parameter for the uris for the incident report id.
     *
     * @hide
     */
    public static final String URI_PARAM_REPORT_ID = "r";

    /**
     * Query parameter for the uris for the pending report id.
     *
     * @hide
     */
    public static final String URI_PARAM_CALLING_PACKAGE = "pkg";

    /**
     * Query parameter for the uris for the pending report id, in wall clock
     * ({@link System.currentTimeMillis()}) timebase.
     *
     * @hide
     */
    public static final String URI_PARAM_TIMESTAMP = "t";

    /**
     * Query parameter for the uris for the pending report id.
     *
     * @hide
     */
    public static final String URI_PARAM_FLAGS = "flags";

    /**
     * Query parameter for the uris for the pending report id.
     *
     * @hide
     */
    public static final String URI_PARAM_RECEIVER_CLASS = "receiver";

    /**
     * Do the confirmation with a dialog instead of the default, which is a notification.
     * It is possible for the dialog to be downgraded to a notification in some cases.
     */
    public static final int FLAG_CONFIRMATION_DIALOG = 0x1;

    /**
     * Flag marking fields and incident reports than can be taken
     * off the device only via adb.
     */
    public static final int PRIVACY_POLICY_LOCAL = 0;

    /**
     * Flag marking fields and incident reports than can be taken
     * off the device with contemporary consent.
     */
    public static final int PRIVACY_POLICY_EXPLICIT = 100;

    /**
     * Flag marking fields and incident reports than can be taken
     * off the device with prior consent.
     */
    public static final int PRIVACY_POLICY_AUTO = 200;

    /** @hide */
    @IntDef(flag = false, prefix = { "PRIVACY_POLICY_" }, value = {
            PRIVACY_POLICY_AUTO,
            PRIVACY_POLICY_EXPLICIT,
            PRIVACY_POLICY_LOCAL,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PrivacyPolicy {}

    private final Context mContext;

    private Object mLock = new Object();
    private IIncidentManager mIncidentService;
    private IIncidentCompanion mCompanionService;

    /**
     * Record for a report that has been taken and is pending user authorization
     * to share it.
     * @hide
     */
    @SystemApi
    @TestApi
    public static class PendingReport {
        /**
         * Encoded data.
         */
        private final Uri mUri;

        /**
         * URI_PARAM_FLAGS from the uri
         */
        private final int mFlags;

        /**
         * URI_PARAM_CALLING_PACKAGE from the uri
         */
        private final String mRequestingPackage;

        /**
         * URI_PARAM_TIMESTAMP from the uri
         */
        private final long mTimestamp;

        /**
         * Constructor.
         */
        public PendingReport(@NonNull Uri uri) {
            int flags = 0;
            try {
                flags = Integer.parseInt(uri.getQueryParameter(URI_PARAM_FLAGS));
            } catch (NumberFormatException ex) {
                throw new RuntimeException("Invalid URI: No " + URI_PARAM_FLAGS
                        + " parameter. " + uri);
            }
            mFlags = flags;

            String requestingPackage = uri.getQueryParameter(URI_PARAM_CALLING_PACKAGE);
            if (requestingPackage == null) {
                throw new RuntimeException("Invalid URI: No " + URI_PARAM_CALLING_PACKAGE
                        + " parameter. " + uri);
            }
            mRequestingPackage = requestingPackage;

            long timestamp = -1;
            try {
                timestamp = Long.parseLong(uri.getQueryParameter(URI_PARAM_TIMESTAMP));
            } catch (NumberFormatException ex) {
                throw new RuntimeException("Invalid URI: No " + URI_PARAM_TIMESTAMP
                        + " parameter. " + uri);
            }
            mTimestamp = timestamp;

            mUri = uri;
        }

        /**
         * Get the package with which this report will be shared.
         */
        public @NonNull String getRequestingPackage() {
            return mRequestingPackage;
        }

        /**
         * Get the flags requested for this pending report.
         *
         * @see #FLAG_CONFIRMATION_DIALOG
         */
        public int getFlags() {
            return mFlags;
        }

        /**
         * Get the time this pending report was posted.
         */
        public long getTimestamp() {
            return mTimestamp;
        }

        /**
         * Get the URI associated with this PendingReport.  It can be used to
         * re-retrieve it from {@link IncidentManager} or set as the data field of
         * an Intent.
         */
        public @NonNull Uri getUri() {
            return mUri;
        }

        /**
         * String representation of this PendingReport.
         */
        @Override
        public @NonNull String toString() {
            return "PendingReport(" + getUri().toString() + ")";
        }

        /**
         * @inheritDoc
         */
        @Override
        public boolean equals(@Nullable Object obj) {
            if (this == obj) {
                return true;
            }
            if (!(obj instanceof PendingReport)) {
                return false;
            }
            final PendingReport that = (PendingReport) obj;
            return this.mUri.equals(that.mUri)
                    && this.mFlags == that.mFlags
                    && this.mRequestingPackage.equals(that.mRequestingPackage)
                    && this.mTimestamp == that.mTimestamp;
        }
    }

    /**
     * Record of an incident report that has previously been taken.
     * @hide
     */
    @SystemApi
    @TestApi
    public static class IncidentReport implements Parcelable, Closeable {
        private final long mTimestampNs;
        private final int mPrivacyPolicy;
        private ParcelFileDescriptor mFileDescriptor;

        public IncidentReport(Parcel in) {
            mTimestampNs = in.readLong();
            mPrivacyPolicy = in.readInt();
            if (in.readInt() != 0) {
                mFileDescriptor = ParcelFileDescriptor.CREATOR.createFromParcel(in);
            } else {
                mFileDescriptor = null;
            }
        }

        /**
         * Close the input stream associated with this entry.
         */
        public void close() {
            try {
                if (mFileDescriptor != null) {
                    mFileDescriptor.close();
                    mFileDescriptor = null;
                }
            } catch (IOException e) {
            }
        }

        /**
         * Get the time at which this incident report was taken, in wall clock time
         * ({@link System#currenttimeMillis System.currenttimeMillis()} time base).
         */
        public long getTimestamp() {
            return mTimestampNs / 1000000;
        }

        /**
         * Get the privacy level to which this report has been filtered.
         *
         * @see #PRIVACY_POLICY_AUTO
         * @see #PRIVACY_POLICY_EXPLICIT
         * @see #PRIVACY_POLICY_LOCAL
         */
        public long getPrivacyPolicy() {
            return mPrivacyPolicy;
        }

        /**
         * Get the contents of this incident report.
         */
        public InputStream getInputStream() throws IOException {
            if (mFileDescriptor == null) {
                return null;
            }
            return new ParcelFileDescriptor.AutoCloseInputStream(mFileDescriptor);
        }

        /**
         * @inheritDoc
         */
        public int describeContents() {
            return mFileDescriptor != null ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0;
        }

        /**
         * @inheritDoc
         */
        public void writeToParcel(Parcel out, int flags) {
            out.writeLong(mTimestampNs);
            out.writeInt(mPrivacyPolicy);
            if (mFileDescriptor != null) {
                out.writeInt(1);
                mFileDescriptor.writeToParcel(out, flags);
            } else {
                out.writeInt(0);
            }
        }

        /**
         * {@link Parcelable.Creator Creator} for {@link IncidentReport}.
         */
        public static final @android.annotation.NonNull Parcelable.Creator<IncidentReport> CREATOR = new Parcelable.Creator() {
            /**
             * @inheritDoc
             */
            public IncidentReport[] newArray(int size) {
                return new IncidentReport[size];
            }

            /**
             * @inheritDoc
             */
            public IncidentReport createFromParcel(Parcel in) {
                return new IncidentReport(in);
            }
        };
    }

    /**
     * Listener for the status of an incident report being authorized or denied.
     *
     * @see #requestAuthorization
     * @see #cancelAuthorization
     */
    public static class AuthListener {
        Executor mExecutor;

        IIncidentAuthListener.Stub mBinder = new IIncidentAuthListener.Stub() {
            @Override
            public void onReportApproved() {
                if (mExecutor != null) {
                    mExecutor.execute(() -> {
                        AuthListener.this.onReportApproved();
                    });
                } else {
                    AuthListener.this.onReportApproved();
                }
            }

            @Override
            public void onReportDenied() {
                if (mExecutor != null) {
                    mExecutor.execute(() -> {
                        AuthListener.this.onReportDenied();
                    });
                } else {
                    AuthListener.this.onReportDenied();
                }
            }
        };

        /**
         * Called when a report is approved.
         */
        public void onReportApproved() {
        }

        /**
         * Called when a report is denied.
         */
        public void onReportDenied() {
        }
    }

    /**
     * @hide
     */
    public IncidentManager(Context context) {
        mContext = context;
    }

    /**
     * Take an incident report.
     */
    @RequiresPermission(allOf = {
            android.Manifest.permission.DUMP,
            android.Manifest.permission.PACKAGE_USAGE_STATS
    })
    public void reportIncident(IncidentReportArgs args) {
        reportIncidentInternal(args);
    }

    /**
     * Request authorization of an incident report.
     */
    @RequiresPermission(android.Manifest.permission.REQUEST_INCIDENT_REPORT_APPROVAL)
    public void requestAuthorization(int callingUid, String callingPackage, int flags,
            AuthListener listener) {
        requestAuthorization(callingUid, callingPackage, flags,
                mContext.getMainExecutor(), listener);
    }

    /**
     * Request authorization of an incident report.
     * @hide
     */
    @RequiresPermission(android.Manifest.permission.REQUEST_INCIDENT_REPORT_APPROVAL)
    public void requestAuthorization(int callingUid, @NonNull String callingPackage, int flags,
             @NonNull @CallbackExecutor Executor executor, @NonNull AuthListener listener) {
        try {
            if (listener.mExecutor != null) {
                throw new RuntimeException("Do not reuse AuthListener objects when calling"
                        + " requestAuthorization");
            }
            listener.mExecutor = executor;
            getCompanionServiceLocked().authorizeReport(callingUid, callingPackage, null, null,
                    flags, listener.mBinder);
        } catch (RemoteException ex) {
            // System process going down
            throw new RuntimeException(ex);
        }
    }

    /**
     * Cancel a previous request for incident report authorization.
     */
    @RequiresPermission(android.Manifest.permission.REQUEST_INCIDENT_REPORT_APPROVAL)
    public void cancelAuthorization(AuthListener listener) {
        try {
            getCompanionServiceLocked().cancelAuthorization(listener.mBinder);
        } catch (RemoteException ex) {
            // System process going down
            throw new RuntimeException(ex);
        }
    }

    /**
     * Get incident (and bug) reports that are pending approval to share.
     */
    @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS)
    public List<PendingReport> getPendingReports() {
        List<String> strings;
        try {
            strings = getCompanionServiceLocked().getPendingReports();
        } catch (RemoteException ex) {
            throw new RuntimeException(ex);
        }
        final int size = strings.size();
        ArrayList<PendingReport> result = new ArrayList(size);
        for (int i = 0; i < size; i++) {
            result.add(new PendingReport(Uri.parse(strings.get(i))));
        }
        return result;
    }

    /**
     * Allow this report to be shared with the given app.
     */
    @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS)
    public void approveReport(Uri uri) {
        try {
            getCompanionServiceLocked().approveReport(uri.toString());
        } catch (RemoteException ex) {
            // System process going down
            throw new RuntimeException(ex);
        }
    }

    /**
     * Do not allow this report to be shared with the given app.
     */
    @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS)
    public void denyReport(Uri uri) {
        try {
            getCompanionServiceLocked().denyReport(uri.toString());
        } catch (RemoteException ex) {
            // System process going down
            throw new RuntimeException(ex);
        }
    }

    /**
     * Get the incident reports that are available for upload for the supplied
     * broadcast recevier.
     *
     * @param receiverClass Class name of broadcast receiver in this package that
     *   was registered to retrieve reports.
     *
     * @return A list of {@link Uri Uris} that are awaiting upload.
     */
    @RequiresPermission(allOf = {
            android.Manifest.permission.DUMP,
            android.Manifest.permission.PACKAGE_USAGE_STATS
    })
    public @NonNull List<Uri> getIncidentReportList(String receiverClass) {
        List<String> strings;
        try {
            strings = getCompanionServiceLocked().getIncidentReportList(
                    mContext.getPackageName(), receiverClass);
        } catch (RemoteException ex) {
            throw new RuntimeException("System server or incidentd going down", ex);
        }
        final int size = strings.size();
        ArrayList<Uri> result = new ArrayList(size);
        for (int i = 0; i < size; i++) {
            result.add(Uri.parse(strings.get(i)));
        }
        return result;
    }

    /**
     * Get the incident report with the given URI id.
     *
     * @param uri Identifier of the incident report.
     *
     * @return an IncidentReport object, or null if the incident report has been
     *  expired from disk.
     */
    @RequiresPermission(allOf = {
            android.Manifest.permission.DUMP,
            android.Manifest.permission.PACKAGE_USAGE_STATS
    })
    public @Nullable IncidentReport getIncidentReport(Uri uri) {
        final String id = uri.getQueryParameter(URI_PARAM_REPORT_ID);
        if (id == null) {
            // If there's no report id, it's a bug report, so we can't return the incident
            // report.
            return null;
        }

        final String pkg = uri.getQueryParameter(URI_PARAM_CALLING_PACKAGE);
        if (pkg == null) {
            throw new RuntimeException("Invalid URI: No "
                    + URI_PARAM_CALLING_PACKAGE + " parameter. " + uri);
        }

        final String cls = uri.getQueryParameter(URI_PARAM_RECEIVER_CLASS);
        if (cls == null) {
            throw new RuntimeException("Invalid URI: No "
                    + URI_PARAM_RECEIVER_CLASS + " parameter. " + uri);
        }

        try {
            return getCompanionServiceLocked().getIncidentReport(pkg, cls, id);
        } catch (RemoteException ex) {
            throw new RuntimeException("System server or incidentd going down", ex);
        }
    }

    /**
     * Delete the incident report with the given URI id.
     *
     * @param uri Identifier of the incident report. Pass null to delete all
     *              incident reports owned by this application.
     */
    @RequiresPermission(allOf = {
            android.Manifest.permission.DUMP,
            android.Manifest.permission.PACKAGE_USAGE_STATS
    })
    public void deleteIncidentReports(Uri uri) {
        if (uri == null) {
            try {
                getCompanionServiceLocked().deleteAllIncidentReports(mContext.getPackageName());
            } catch (RemoteException ex) {
                throw new RuntimeException("System server or incidentd going down", ex);
            }
        } else {
            final String pkg = uri.getQueryParameter(URI_PARAM_CALLING_PACKAGE);
            if (pkg == null) {
                throw new RuntimeException("Invalid URI: No "
                        + URI_PARAM_CALLING_PACKAGE + " parameter. " + uri);
            }

            final String cls = uri.getQueryParameter(URI_PARAM_RECEIVER_CLASS);
            if (cls == null) {
                throw new RuntimeException("Invalid URI: No "
                        + URI_PARAM_RECEIVER_CLASS + " parameter. " + uri);
            }

            final String id = uri.getQueryParameter(URI_PARAM_REPORT_ID);
            if (id == null) {
                throw new RuntimeException("Invalid URI: No "
                        + URI_PARAM_REPORT_ID + " parameter. " + uri);
            }
        
            try {
                getCompanionServiceLocked().deleteIncidentReports(pkg, cls, id);
            } catch (RemoteException ex) {
                throw new RuntimeException("System server or incidentd going down", ex);
            }
        }
    }

    private void reportIncidentInternal(IncidentReportArgs args) {
        try {
            final IIncidentManager service = getIIncidentManagerLocked();
            if (service == null) {
                Slog.e(TAG, "reportIncident can't find incident binder service");
                return;
            }
            service.reportIncident(args);
        } catch (RemoteException ex) {
            Slog.e(TAG, "reportIncident failed", ex);
        }
    }

    private IIncidentManager getIIncidentManagerLocked() throws RemoteException {
        if (mIncidentService != null) {
            return mIncidentService;
        }

        synchronized (mLock) {
            if (mIncidentService != null) {
                return mIncidentService;
            }
            mIncidentService = IIncidentManager.Stub.asInterface(
                ServiceManager.getService(Context.INCIDENT_SERVICE));
            if (mIncidentService != null) {
                mIncidentService.asBinder().linkToDeath(() -> {
                    synchronized (mLock) {
                        mIncidentService = null;
                    }
                }, 0);
            }
            return mIncidentService;
        }
    }

    private IIncidentCompanion getCompanionServiceLocked() throws RemoteException {
        if (mCompanionService != null) {
            return mCompanionService;
        }

        synchronized (this) {
            if (mCompanionService != null) {
                return mCompanionService;
            }
            mCompanionService = IIncidentCompanion.Stub.asInterface(
                ServiceManager.getService(Context.INCIDENT_COMPANION_SERVICE));
            if (mCompanionService != null) {
                mCompanionService.asBinder().linkToDeath(() -> {
                    synchronized (mLock) {
                        mCompanionService = null;
                    }
                }, 0);
            }
            return mCompanionService;
        }
    }
}

