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

/**
 * 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 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";

    /**
     * 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() + ")";
        }
    }

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

        public IncidentReport(Parcel in) {
            mTimestampMs = 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#uptimeMillis System.uptimeMillis()} time base).
         */
        public long getTimestamp() {
            return mTimestampMs;
        }

        /**
         * 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(mTimestampMs);
            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 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 authroized or denied.
     *
     * @see #requestAuthorization
     * @see #cancelAuthorization
     */
    public static class AuthListener {
        IIncidentAuthListener.Stub mBinder = new IIncidentAuthListener.Stub() {
            @Override
            public void onReportApproved() {
                AuthListener.this.onReportApproved();
            }

            @Override
            public void onReportDenied() {
                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) {
        try {
            getCompanionServiceLocked().authorizeReport(callingUid, callingPackage, 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) {
        throw new RuntimeException("implement me");
    }

    /**
     * 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) {
        throw new RuntimeException("implement me");
    }

    /**
     * Delete the incident report with the given URI id.
     *
     * @param uri Identifier of the incident report.
     */
    @RequiresPermission(allOf = {
            android.Manifest.permission.DUMP,
            android.Manifest.permission.PACKAGE_USAGE_STATS
    })
    public void deleteIncidentReports(Uri uri) {
        throw new RuntimeException("implement me");
    }

    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;
        }
    }
}

