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

import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;

import android.annotation.Nullable;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Debug;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.Log;

import androidx.core.content.FileProvider;

import com.google.android.collect.Lists;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

/**
 * Dumps data to debug leaks and posts a notification to share the data.
 */
@Singleton
public class LeakReporter {

    static final String TAG = "LeakReporter";

    public static final String FILEPROVIDER_AUTHORITY = "com.android.systemui.fileprovider";

    static final String LEAK_DIR = "leak";
    static final String LEAK_HPROF = "leak.hprof";
    static final String LEAK_DUMP = "leak.dump";

    private final Context mContext;
    private final LeakDetector mLeakDetector;
    private final String mLeakReportEmail;

    @Inject
    public LeakReporter(Context context, LeakDetector leakDetector,
            @Nullable @Named(LEAK_REPORT_EMAIL_NAME) String leakReportEmail) {
        mContext = context;
        mLeakDetector = leakDetector;
        mLeakReportEmail = leakReportEmail;
    }

    public void dumpLeak(int garbageCount) {
        try {
            File leakDir = new File(mContext.getCacheDir(), LEAK_DIR);
            leakDir.mkdir();

            File hprofFile = new File(leakDir, LEAK_HPROF);
            Debug.dumpHprofData(hprofFile.getAbsolutePath());

            File dumpFile = new File(leakDir, LEAK_DUMP);
            try (FileOutputStream fos = new FileOutputStream(dumpFile)) {
                PrintWriter w = new PrintWriter(fos);
                w.print("Build: "); w.println(SystemProperties.get("ro.build.description"));
                w.println();
                w.flush();
                mLeakDetector.dump(fos.getFD(), w, new String[0]);
                w.close();
            }

            NotificationManager notiMan = mContext.getSystemService(NotificationManager.class);

            NotificationChannel channel = new NotificationChannel("leak", "Leak Alerts",
                    NotificationManager.IMPORTANCE_HIGH);
            channel.enableVibration(true);

            notiMan.createNotificationChannel(channel);
            Notification.Builder builder = new Notification.Builder(mContext, channel.getId())
                    .setAutoCancel(true)
                    .setShowWhen(true)
                    .setContentTitle("Memory Leak Detected")
                    .setContentText(String.format(
                            "SystemUI has detected %d leaked objects. Tap to send", garbageCount))
                    .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                    .setContentIntent(PendingIntent.getActivityAsUser(
                            mContext,
                            0,
                            getIntent(hprofFile, dumpFile),
                            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE,
                            null,
                            UserHandle.CURRENT));
            notiMan.notify(TAG, 0, builder.build());
        } catch (IOException e) {
            Log.e(TAG, "Couldn't dump heap for leak", e);
        }
    }

    private Intent getIntent(File hprofFile, File dumpFile) {
        Uri dumpUri = FileProvider.getUriForFile(mContext, FILEPROVIDER_AUTHORITY, dumpFile);
        Uri hprofUri = FileProvider.getUriForFile(mContext, FILEPROVIDER_AUTHORITY, hprofFile);

        Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
        String mimeType = "application/vnd.android.leakreport";

        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setType(mimeType);

        final String subject = "SystemUI leak report";
        intent.putExtra(Intent.EXTRA_SUBJECT, subject);

        // EXTRA_TEXT should be an ArrayList, but some clients are expecting a single String.
        // So, to avoid an exception on Intent.migrateExtraStreamToClipData(), we need to manually
        // create the ClipData object with the attachments URIs.
        final StringBuilder messageBody = new StringBuilder("Build info: ")
                .append(SystemProperties.get("ro.build.description"));
        intent.putExtra(Intent.EXTRA_TEXT, messageBody.toString());
        final ClipData clipData = new ClipData(null, new String[] { mimeType },
                new ClipData.Item(null, null, null, dumpUri));
        final ArrayList<Uri> attachments = Lists.newArrayList(dumpUri);

        clipData.addItem(new ClipData.Item(null, null, null, hprofUri));
        attachments.add(hprofUri);

        intent.setClipData(clipData);
        intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachments);

        String leakReportEmail = mLeakReportEmail;
        if (leakReportEmail != null) {
            intent.putExtra(Intent.EXTRA_EMAIL, new String[] { leakReportEmail });
        }

        return intent;
    }
}
