/*
 * 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 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.support.v4.content.FileProvider;
import android.util.Log;

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;

/**
 * Dumps data to debug leaks and posts a notification to share the data.
 */
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;

    public LeakReporter(Context context, LeakDetector leakDetector, 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, 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;
    }
}
