/*
 * Copyright (C) 2011 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.commands.sendbug;

import android.accounts.Account;
import android.accounts.IAccountManager;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.Log;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

public class SendBug {

    private static final String LOG_TAG = SendBug.class.getSimpleName();
    private static final Pattern EMAIL_REGEX = Pattern.compile(
            "^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$");
    private static final String SEND_BUG_INTENT_ACTION = "android.testing.SEND_BUG";

    public static void main(String[] args) {
        if (args.length == 1) {
            new SendBug().run(args[0]);
        } else if (args.length == 2) {
            new SendBug().run(args[0], args[1]);
        }
    }

    private void run(String bugreportPath) {
        run(bugreportPath, null);
    }

    private void run(String bugreportPath, String screenShotPath) {
        final File bugreport = new File(bugreportPath);
        File screenShot = null;
        if (screenShotPath != null) {
            screenShot = new File(screenShotPath);
        }
        final Uri bugreportUri = Uri.fromFile(bugreport);
        // todo (aalbert): investigate adding a screenshot to BugReporter
        Intent intent = tryBugReporter(bugreportUri);
        if (intent == null) {
            final Uri screenshotUri = screenShot != null
                    ? Uri.fromFile(screenShot) : null;
            intent = getSendMailIntent(bugreportUri, screenshotUri);
        }
        if (intent != null) {
            final IActivityManager am = ActivityManagerNative.getDefault();
            if (am == null) {
                Log.e(LOG_TAG, "Cannot get ActivityManager, is the system running?");
                return;
            }
            try {
                am.startActivityAsUser(null, null, intent, intent.getType(), null, null, 0, 0,
                        null, null, null, UserHandle.USER_CURRENT);
            } catch (RemoteException e) {
                // ignore
            }
        } else {
            Log.w(LOG_TAG, "Cannot find account to send bugreport, local path: "
                    + bugreportPath);
        }
    }

    private Intent tryBugReporter(Uri bugreportUri) {
        final Intent intent = new Intent(SEND_BUG_INTENT_ACTION);
        intent.setData(bugreportUri);
        final IPackageManager pm = IPackageManager.Stub.asInterface(
                ServiceManager.getService("package"));
        if (pm == null) {
            Log.e(LOG_TAG, "Cannot get PackageManager, is the system running?");
            return null;
        }
        final List<ResolveInfo> results;
        try {
            results = pm.queryIntentActivities(intent, null, 0, 0);
        } catch (RemoteException e) {
            return null;
        }
        if (results != null && results.size() > 0) {
            final ResolveInfo info = results.get(0);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setClassName(info.activityInfo.applicationInfo.packageName,
                    info.activityInfo.name);
            return intent;
        } else {
            return null;
        }
    }

    private Intent getSendMailIntent(Uri bugreportUri, Uri screenshotUri) {
        final Account sendToAccount = findSendToAccount();
        final Intent intent = new Intent(Intent.ACTION_SEND);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setType("application/octet-stream");
        intent.putExtra(Intent.EXTRA_SUBJECT, bugreportUri.getLastPathSegment());
        final StringBuilder sb = new StringBuilder();
        sb.append(SystemProperties.get("ro.build.description"));
        sb.append("\n(Sent from BugMailer)");
        intent.putExtra(Intent.EXTRA_TEXT, (CharSequence)sb);
        if (screenshotUri != null) {
            final ArrayList<Uri> attachments = new ArrayList<Uri>();
            attachments.add(bugreportUri);
            attachments.add(screenshotUri);
            intent.setAction(Intent.ACTION_SEND_MULTIPLE);
            intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, attachments);
        } else {
            intent.putExtra(Intent.EXTRA_STREAM, bugreportUri);
        }
        if (sendToAccount != null) {
            intent.putExtra(Intent.EXTRA_EMAIL, new String[]{sendToAccount.name});
            return intent;
        }
        return null;
    }

    private Account findSendToAccount() {
        final IAccountManager accountManager = IAccountManager.Stub.asInterface(ServiceManager
                .getService(Context.ACCOUNT_SERVICE));
        if (accountManager == null) {
            Log.e(LOG_TAG, "Cannot get AccountManager, is the system running?");
            return null;
        }
        Account[] accounts = null;
        Account foundAccount = null;
        String preferredDomain = SystemProperties.get("sendbug.preferred.domain");
        if (!preferredDomain.startsWith("@")) {
            preferredDomain = "@" + preferredDomain;
        }
        try {
            accounts = accountManager.getAccounts(null);
        } catch (RemoteException e) {
            // ignore
        }
        if (accounts != null) {
            for (Account account : accounts) {
                if (EMAIL_REGEX.matcher(account.name).matches()) {
                    if (!preferredDomain.isEmpty()) {
                        // if we have a preferred domain and it matches, return; otherwise keep
                        // looking
                        if (account.name.endsWith(preferredDomain)) {
                            return account;
                        } else {
                            foundAccount = account;
                        }
                        // if we don't have a preferred domain, just return since it looks like
                        // an email address
                    } else {
                        return account;
                    }
                }
            }
        }
        return foundAccount;
    }
}
