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

#include "aapt.h"
#include "adb.h"
#include "make.h"
#include "print.h"
#include "util.h"

#include <sstream>
#include <string>
#include <vector>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <google/protobuf/stubs/common.h>

using namespace std;

/**
 * An entry from the command line for something that will be built, installed,
 * and/or tested.
 */
struct Target {
    bool build;
    bool install;
    bool test;
    string pattern;
    string name;
    vector<string> actions;
    Module module;

    int testActionCount;

    int testPassCount;
    int testFailCount;
    int unknownFailureCount; // unknown failure == "Process crashed", etc.
    bool actionsWithNoTests;

    Target(bool b, bool i, bool t, const string& p);
};

Target::Target(bool b, bool i, bool t, const string& p)
    :build(b),
     install(i),
     test(t),
     pattern(p),
     testActionCount(0),
     testPassCount(0),
     testFailCount(0),
     unknownFailureCount(0),
     actionsWithNoTests(false)
{
}

/**
 * Command line options.
 */
struct Options {
    // For help
    bool runHelp;

    // For tab completion
    bool runTab;
    string tabPattern;

    // For build/install/test
    bool noRestart;
    bool reboot;
    vector<Target*> targets;

    Options();
    ~Options();
};

Options::Options()
    :runHelp(false),
     runTab(false),
     noRestart(false),
     reboot(false),
     targets()
{
}

Options::~Options()
{
}

struct InstallApk
{
    TrackedFile file;
    bool alwaysInstall;
    bool installed;

    InstallApk();
    InstallApk(const InstallApk& that);
    InstallApk(const string& filename, bool always);
    ~InstallApk() {};
};

InstallApk::InstallApk()
{
}

InstallApk::InstallApk(const InstallApk& that)
    :file(that.file),
     alwaysInstall(that.alwaysInstall),
     installed(that.installed)
{
}

InstallApk::InstallApk(const string& filename, bool always)
    :file(filename),
     alwaysInstall(always),
     installed(false)
{
}


/**
 * Record for an test that is going to be launched.
 */
struct TestAction {
    TestAction();

    // The package name from the apk
    string packageName;

    // The test runner class
    string runner;

    // The test class, or none if all tests should be run
    string className;

    // The original target that requested this action
    Target* target;

    // The number of tests that passed
    int passCount;

    // The number of tests that failed
    int failCount;
};

TestAction::TestAction()
    :passCount(0),
     failCount(0)
{
}

/**
 * Record for an activity that is going to be launched.
 */
struct ActivityAction {
    // The package name from the apk
    string packageName;

    // The test class, or none if all tests should be run
    string className;
};

/**
 * Callback class for the am instrument command.
 */
class TestResults: public InstrumentationCallbacks
{
public:
    virtual void OnTestStatus(TestStatus& status);
    virtual void OnSessionStatus(SessionStatus& status);

    /**
     * Set the TestAction that the tests are for.
     * It will be updated with statistics as the tests run.
     */
    void SetCurrentAction(TestAction* action);

    bool IsSuccess();

    string GetErrorMessage();

private:
    TestAction* m_currentAction;
    SessionStatus m_sessionStatus;
};

void
TestResults::OnTestStatus(TestStatus& status)
{
    bool found;
//    printf("OnTestStatus\n");
//    status.PrintDebugString();
    int32_t resultCode = status.has_results() ? status.result_code() : 0;

    if (!status.has_results()) {
        return;
    }
    const ResultsBundle &results = status.results();

    int32_t currentTestNum = get_bundle_int(results, &found, "current", NULL);
    if (!found) {
        currentTestNum = -1;
    }

    int32_t testCount = get_bundle_int(results, &found, "numtests", NULL);
    if (!found) {
        testCount = -1;
    }

    string className = get_bundle_string(results, &found, "class", NULL);
    if (!found) {
        return;
    }

    string testName = get_bundle_string(results, &found, "test", NULL);
    if (!found) {
        return;
    }

    if (resultCode == 0) {
        // test passed
        m_currentAction->passCount++;
        m_currentAction->target->testPassCount++;
    } else if (resultCode == 1) {
        // test starting
        ostringstream line;
        line << "Running";
        if (currentTestNum > 0) {
            line << ": " << currentTestNum;
            if (testCount > 0) {
                line << " of " << testCount;
            }
        }
        line << ": " << m_currentAction->target->name << ':' << className << "\\#" << testName;
        print_one_line("%s", line.str().c_str());
    } else if ((resultCode == -1) || (resultCode == -2)) {
        // test failed
        // Note -2 means an assertion failure, and -1 means other exceptions.  We just treat them
        // all as "failures".
        m_currentAction->failCount++;
        m_currentAction->target->testFailCount++;
        printf("%s\n%sFailed: %s:%s\\#%s%s\n", g_escapeClearLine, g_escapeRedBold,
                m_currentAction->target->name.c_str(), className.c_str(),
                testName.c_str(), g_escapeEndColor);

        string stack = get_bundle_string(results, &found, "stack", NULL);
        if (found) {
            printf("%s\n", stack.c_str());
        }
    }
}

void
TestResults::OnSessionStatus(SessionStatus& status)
{
    //status.PrintDebugString();
    m_sessionStatus = status;
    if (m_currentAction && !IsSuccess()) {
        m_currentAction->target->unknownFailureCount++;
    }
}

void
TestResults::SetCurrentAction(TestAction* action)
{
    m_currentAction = action;
}

bool
TestResults::IsSuccess()
{
    return m_sessionStatus.result_code() == -1; // Activity.RESULT_OK.
}

string
TestResults::GetErrorMessage()
{
    bool found;
    string shortMsg = get_bundle_string(m_sessionStatus.results(), &found, "shortMsg", NULL);
    if (!found) {
        return IsSuccess() ? "" : "Unknown failure";
    }
    return shortMsg;
}


/**
 * Prints the usage statement / help text.
 */
static void
print_usage(FILE* out) {
    fprintf(out, "usage: bit OPTIONS PATTERN\n");
    fprintf(out, "\n");
    fprintf(out, "  Build, sync and test android code.\n");
    fprintf(out, "\n");
    fprintf(out, "  The -b -i and -t options allow you to specify which phases\n");
    fprintf(out, "  you want to run. If none of those options are given, then\n");
    fprintf(out, "  all phases are run. If any of these options are provided\n");
    fprintf(out, "  then only the listed phases are run.\n");
    fprintf(out, "\n");
    fprintf(out, "  OPTIONS\n");
    fprintf(out, "  -b     Run a build\n");
    fprintf(out, "  -i     Install the targets\n");
    fprintf(out, "  -t     Run the tests\n");
    fprintf(out, "\n");
    fprintf(out, "  -n     Don't reboot or restart\n");
    fprintf(out, "  -r     If the runtime needs to be restarted, do a full reboot\n");
    fprintf(out, "         instead\n");
    fprintf(out, "\n");
    fprintf(out, "  PATTERN\n");
    fprintf(out, "  One or more targets to build, install and test. The target\n");
    fprintf(out, "  names are the names that appear in the LOCAL_MODULE or\n");
    fprintf(out, "  LOCAL_PACKAGE_NAME variables in Android.mk or Android.bp files.\n");
    fprintf(out, "\n");
    fprintf(out, "  Building and installing\n");
    fprintf(out, "  -----------------------\n");
    fprintf(out, "  The modules specified will be built and then installed. If the\n");
    fprintf(out, "  files are on the system partition, they will be synced and the\n");
    fprintf(out, "  attached device rebooted. If they are APKs that aren't on the\n");
    fprintf(out, "  system partition they are installed with adb install.\n");
    fprintf(out, "\n");
    fprintf(out, "  For example:\n");
    fprintf(out, "    bit framework\n");
    fprintf(out, "      Builds framework.jar, syncs the system partition and reboots.\n");
    fprintf(out, "\n");
    fprintf(out, "    bit SystemUI\n");
    fprintf(out, "      Builds SystemUI.apk, syncs the system partition and reboots.\n");
    fprintf(out, "\n");
    fprintf(out, "    bit CtsProtoTestCases\n");
    fprintf(out, "      Builds this CTS apk, adb installs it, but does not run any\n");
    fprintf(out, "      tests.\n");
    fprintf(out, "\n");
    fprintf(out, "  Running Unit Tests\n");
    fprintf(out, "  ------------------\n");
    fprintf(out, "  To run a unit test, list the test class names and optionally the\n");
    fprintf(out, "  test method after the module.\n");
    fprintf(out, "\n");
    fprintf(out, "  For example:\n");
    fprintf(out, "    bit CtsProtoTestCases:*\n");
    fprintf(out, "      Builds this CTS apk, adb installs it, and runs all the tests\n");
    fprintf(out, "      contained in that apk.\n");
    fprintf(out, "\n");
    fprintf(out, "    bit framework CtsProtoTestCases:*\n");
    fprintf(out, "      Builds the framework and the apk, syncs and reboots, then\n");
    fprintf(out, "      adb installs CtsProtoTestCases.apk, and runs all tests \n");
    fprintf(out, "      contained in that apk.\n");
    fprintf(out, "\n");
    fprintf(out, "    bit CtsProtoTestCases:.ProtoOutputStreamBoolTest\n");
    fprintf(out, "    bit CtsProtoTestCases:android.util.proto.cts.ProtoOutputStreamBoolTest\n");
    fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs all the\n");
    fprintf(out, "      tests in the ProtoOutputStreamBoolTest class.\n");
    fprintf(out, "\n");
    fprintf(out, "    bit CtsProtoTestCases:.ProtoOutputStreamBoolTest\\#testWrite\n");
    fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs the testWrite\n");
    fprintf(out, "      test method on that class.\n");
    fprintf(out, "\n");
    fprintf(out, "    bit CtsProtoTestCases:.ProtoOutputStreamBoolTest\\#testWrite,.ProtoOutputStreamBoolTest\\#testRepeated\n");
    fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs the testWrite\n");
    fprintf(out, "      and testRepeated test methods on that class.\n");
    fprintf(out, "\n");
    fprintf(out, "    bit CtsProtoTestCases:android.util.proto.cts.\n");
    fprintf(out, "      Builds and installs CtsProtoTestCases.apk, and runs the tests in the java package\n");
    fprintf(out, "      \"android.util.proto.cts\".\n");
    fprintf(out, "\n");
    fprintf(out, "  Launching an Activity\n");
    fprintf(out, "  ---------------------\n");
    fprintf(out, "  To launch an activity, specify the activity class name after\n");
    fprintf(out, "  the module name.\n");
    fprintf(out, "\n");
    fprintf(out, "  For example:\n");
    fprintf(out, "    bit StatusBarTest:NotificationBuilderTest\n");
    fprintf(out, "    bit StatusBarTest:.NotificationBuilderTest\n");
    fprintf(out, "    bit StatusBarTest:com.android.statusbartest.NotificationBuilderTest\n");
    fprintf(out, "      Builds and installs StatusBarTest.apk, launches the\n");
    fprintf(out, "      com.android.statusbartest/.NotificationBuilderTest activity.\n");
    fprintf(out, "\n");
    fprintf(out, "\n");
    fprintf(out, "usage: bit --tab ...\n");
    fprintf(out, "\n");
    fprintf(out, "  Lists the targets in a format for tab completion. To get tab\n");
    fprintf(out, "  completion, add this to your bash environment:\n");
    fprintf(out, "\n");
    fprintf(out, "     complete -C \"bit --tab\" bit\n");
    fprintf(out, "\n");
    fprintf(out, "  Sourcing android's build/envsetup.sh will do this for you\n");
    fprintf(out, "  automatically.\n");
    fprintf(out, "\n");
    fprintf(out, "\n");
    fprintf(out, "usage: bit --help\n");
    fprintf(out, "usage: bit -h\n");
    fprintf(out, "\n");
    fprintf(out, "  Print this help message\n");
    fprintf(out, "\n");
}


/**
 * Sets the appropriate flag* variables. If there is a problem with the
 * commandline arguments, prints the help message and exits with an error.
 */
static void
parse_args(Options* options, int argc, const char** argv)
{
    // Help
    if (argc == 2 && (strcmp(argv[1],  "-h") == 0 || strcmp(argv[1], "--help") == 0)) {
        options->runHelp = true;
        return;
    }

    // Tab
    if (argc >= 4 && strcmp(argv[1], "--tab") == 0) {
        options->runTab = true;
        options->tabPattern = argv[3];
        return;
    }

    // Normal usage
    bool anyPhases = false;
    bool gotPattern = false;
    bool flagBuild = false;
    bool flagInstall = false;
    bool flagTest = false;
    for (int i=1; i < argc; i++) {
        string arg(argv[i]);
        if (arg[0] == '-') {
            for (size_t j=1; j<arg.size(); j++) {
                switch (arg[j]) {
                    case '-':
                        break;
                    case 'b':
                        if (gotPattern) {
                            gotPattern = false;
                            flagInstall = false;
                            flagTest = false;
                        }
                        flagBuild = true;
                        anyPhases = true;
                        break;
                    case 'i':
                        if (gotPattern) {
                            gotPattern = false;
                            flagBuild = false;
                            flagTest = false;
                        }
                        flagInstall = true;
                        anyPhases = true;
                        break;
                    case 't':
                        if (gotPattern) {
                            gotPattern = false;
                            flagBuild = false;
                            flagInstall = false;
                        }
                        flagTest = true;
                        anyPhases = true;
                        break;
                    case 'n':
                        options->noRestart = true;
                        break;
                    case 'r':
                        options->reboot = true;
                        break;
                    default:
                        fprintf(stderr, "Unrecognized option '%c'\n", arg[j]);
                        print_usage(stderr);
                        exit(1);
                        break;
                }
            }
        } else {
            Target* target = new Target(flagBuild || !anyPhases, flagInstall || !anyPhases,
                    flagTest || !anyPhases, arg);
            size_t colonPos = arg.find(':');
            if (colonPos == 0) {
                fprintf(stderr, "Test / activity supplied without a module to build: %s\n",
                        arg.c_str());
                print_usage(stderr);
                delete target;
                exit(1);
            } else if (colonPos == string::npos) {
                target->name = arg;
            } else {
                target->name.assign(arg, 0, colonPos);
                size_t beginPos = colonPos+1;
                size_t commaPos;
                while (true) {
                    commaPos = arg.find(',', beginPos);
                    if (commaPos == string::npos) {
                        if (beginPos != arg.size()) {
                            target->actions.push_back(string(arg, beginPos, commaPos));
                        }
                        break;
                    } else {
                        if (commaPos != beginPos) {
                            target->actions.push_back(string(arg, beginPos, commaPos-beginPos));
                        }
                        beginPos = commaPos+1;
                    }
                }
            }
            options->targets.push_back(target);
            gotPattern = true;
        }
    }
    // If no pattern was supplied, give an error
    if (options->targets.size() == 0) {
        fprintf(stderr, "No PATTERN supplied.\n\n");
        print_usage(stderr);
        exit(1);
    }
}

/**
 * Get an environment variable.
 * Exits with an error if it is unset or the empty string.
 */
static string
get_required_env(const char* name, bool quiet)
{
    const char* value = getenv(name);
    if (value == NULL || value[0] == '\0') {
        if (!quiet) {
            fprintf(stderr, "%s not set. Did you source build/envsetup.sh,"
                    " run lunch and do a build?\n", name);
        }
        exit(1);
    }
    return string(value);
}

/**
 * Get the out directory.
 *
 * This duplicates the logic in build/make/core/envsetup.mk (which hasn't changed since 2011)
 * so that we don't have to wait for get_build_var make invocation.
 */
string
get_out_dir()
{
    const char* out_dir = getenv("OUT_DIR");
    if (out_dir == NULL || out_dir[0] == '\0') {
        const char* common_base = getenv("OUT_DIR_COMMON_BASE");
        if (common_base == NULL || common_base[0] == '\0') {
            // We don't prefix with buildTop because we cd there and it
            // makes all the filenames long when being pretty printed.
            return "out";
        } else {
            char pwd[PATH_MAX];
            if (getcwd(pwd, PATH_MAX) == NULL) {
                fprintf(stderr, "Your pwd is too long.\n");
                exit(1);
            }
            const char* slash = strrchr(pwd, '/');
            if (slash == NULL) {
                slash = "";
            }
            string result(common_base);
            result += slash;
            return result;
        }
    }
    return string(out_dir);
}

/**
 * Check that a system property on the device matches the expected value.
 * Exits with an error if they don't.
 */
static void
check_device_property(const string& property, const string& expected)
{
    int err;
    string deviceValue = get_system_property(property, &err);
    check_error(err);
    if (deviceValue != expected) {
        print_error("There is a mismatch between the build you just did and the device you");
        print_error("are trying to sync it to in the %s system property", property.c_str());
        print_error("   build:  %s", expected.c_str());
        print_error("   device: %s", deviceValue.c_str());
        exit(1);
    }
}

static void
chdir_or_exit(const char *path) {
    // TODO: print_command("cd", path);
    if (0 != chdir(path)) {
        print_error("Error: Could not chdir: %s", path);
        exit(1);
    }
}

/**
 * Run the build, install, and test actions.
 */
bool
run_phases(vector<Target*> targets, const Options& options)
{
    int err = 0;

    //
    // Initialization
    //

    print_status("Initializing");

    const string buildTop = get_required_env("ANDROID_BUILD_TOP", false);
    const string buildProduct = get_required_env("TARGET_PRODUCT", false);
    const string buildVariant = get_required_env("TARGET_BUILD_VARIANT", false);
    const string buildType = get_required_env("TARGET_BUILD_TYPE", false);

    chdir_or_exit(buildTop.c_str());

    const string buildDevice = get_build_var("TARGET_DEVICE", false);
    const string buildId = get_build_var("BUILD_ID", false);
    const string buildOut = get_out_dir();

    // Get the modules for the targets
    map<string,Module> modules;
    read_modules(buildOut, buildDevice, &modules, false);
    for (size_t i=0; i<targets.size(); i++) {
        Target* target = targets[i];
        map<string,Module>::iterator mod = modules.find(target->name);
        if (mod != modules.end()) {
            target->module = mod->second;
        } else {
            print_error("Error: Could not find module: %s", target->name.c_str());
            err = 1;
        }
    }
    if (err != 0) {
        exit(1);
    }

    // Choose the goals
    vector<string> goals;
    for (size_t i=0; i<targets.size(); i++) {
        Target* target = targets[i];
        if (target->build) {
            goals.push_back(target->name);
        }
    }

    // Figure out whether we need to sync the system and which apks to install
    string systemPath = buildOut + "/target/product/" + buildDevice + "/system/";
    string dataPath = buildOut + "/target/product/" + buildDevice + "/data/";
    bool syncSystem = false;
    bool alwaysSyncSystem = false;
    vector<InstallApk> installApks;
    for (size_t i=0; i<targets.size(); i++) {
        Target* target = targets[i];
        if (target->install) {
            for (size_t j=0; j<target->module.installed.size(); j++) {
                const string& file = target->module.installed[j];
                // System partition
                if (starts_with(file, systemPath)) {
                    syncSystem = true;
                    if (!target->build) {
                        // If a system partition target didn't get built then
                        // it won't change we will always need to do adb sync
                        alwaysSyncSystem = true;
                    }
                    continue;
                }
                // Apk in the data partition
                if (starts_with(file, dataPath) && ends_with(file, ".apk")) {
                    // Always install it if we didn't build it because otherwise
                    // it will never have changed.
                    installApks.push_back(InstallApk(file, !target->build));
                    continue;
                }
            }
        }
    }
    map<string,FileInfo> systemFilesBefore;
    if (syncSystem && !alwaysSyncSystem) {
        get_directory_contents(systemPath, &systemFilesBefore);
    }

    //
    // Build
    //

    // Run the build
    if (goals.size() > 0) {
        print_status("Building");
        err = build_goals(goals);
        check_error(err);
    }

    //
    // Install
    //

    // Sync the system partition and reboot
    bool skipSync = false;
    if (syncSystem) {
        print_status("Syncing /system");

        if (!alwaysSyncSystem) {
            // If nothing changed and we weren't forced to sync, skip the reboot for speed.
            map<string,FileInfo> systemFilesAfter;
            get_directory_contents(systemPath, &systemFilesAfter);
            skipSync = !directory_contents_differ(systemFilesBefore, systemFilesAfter);
        }
        if (skipSync) {
            printf("Skipping sync because no files changed.\n");
        } else {
            // Do some sanity checks
            check_device_property("ro.build.product", buildProduct);
            check_device_property("ro.build.type", buildVariant);
            check_device_property("ro.build.id", buildId);

            // Stop & Sync
            if (!options.noRestart) {
                err = run_adb("shell", "stop", NULL);
                check_error(err);
            }
            err = run_adb("remount", NULL);
            check_error(err);
            err = run_adb("sync", "system", NULL);
            check_error(err);

            if (!options.noRestart) {
                if (options.reboot) {
                    print_status("Rebooting");

                    err = run_adb("reboot", NULL);
                    check_error(err);
                    err = run_adb("wait-for-device", NULL);
                    check_error(err);
                } else {
                    print_status("Restarting the runtime");

                    err = run_adb("shell", "setprop", "sys.boot_completed", "0", NULL);
                    check_error(err);
                    err = run_adb("shell", "start", NULL);
                    check_error(err);
                }

                while (true) {
                    string completed = get_system_property("sys.boot_completed", &err);
                    check_error(err);
                    if (completed == "1") {
                        break;
                    }
                    sleep(2);
                }
                sleep(1);
                err = run_adb("shell", "wm", "dismiss-keyguard", NULL);
                check_error(err);
            }
        }
    }

    // Install APKs
    if (installApks.size() > 0) {
        print_status("Installing APKs");
        for (size_t i=0; i<installApks.size(); i++) {
            InstallApk& apk = installApks[i];
            if (!apk.file.fileInfo.exists || apk.file.HasChanged()) {
                // It didn't exist before or it changed, so int needs install
                err = run_adb("install", "-r", "-g", apk.file.filename.c_str(), NULL);
                check_error(err);
                apk.installed = true;
            } else {
                printf("APK didn't change. Skipping install of %s\n", apk.file.filename.c_str());
            }
        }
    }

    //
    // Actions
    //

    // Inspect the apks, and figure out what is an activity and what needs a test runner
    bool printedInspecting = false;
    vector<TestAction> testActions;
    vector<ActivityAction> activityActions;
    for (size_t i=0; i<targets.size(); i++) {
        Target* target = targets[i];
        if (target->test) {
            for (size_t j=0; j<target->module.installed.size(); j++) {
                string filename = target->module.installed[j];

                if (!ends_with(filename, ".apk")) {
                    continue;
                }

                if (!printedInspecting) {
                    printedInspecting = true;
                    print_status("Inspecting APKs");
                }

                Apk apk;
                err = inspect_apk(&apk, filename);
                check_error(err);

                for (size_t k=0; k<target->actions.size(); k++) {
                    string actionString = target->actions[k];
                    if (actionString == "*") {
                        if (apk.runner.length() == 0) {
                            print_error("Error: Test requested for apk that doesn't"
                                    " have an <instrumentation> tag: %s\n",
                                    target->module.name.c_str());
                            exit(1);
                        }
                        TestAction action;
                        action.packageName = apk.package;
                        action.runner = apk.runner;
                        action.target = target;
                        testActions.push_back(action);
                        target->testActionCount++;
                    } else if (apk.HasActivity(actionString)) {
                        ActivityAction action;
                        action.packageName = apk.package;
                        action.className = full_class_name(apk.package, actionString);
                        activityActions.push_back(action);
                    } else {
                        if (apk.runner.length() == 0) {
                            print_error("Error: Test requested for apk that doesn't"
                                    " have an <instrumentation> tag: %s\n",
                                    target->module.name.c_str());
                            exit(1);
                        }
                        TestAction action;
                        action.packageName = apk.package;
                        action.runner = apk.runner;
                        action.className = full_class_name(apk.package, actionString);
                        action.target = target;
                        testActions.push_back(action);
                        target->testActionCount++;
                    }
                }
            }
        }
    }

    // Run the instrumentation tests
    TestResults testResults;
    if (testActions.size() > 0) {
        print_status("Running tests");
        for (size_t i=0; i<testActions.size(); i++) {
            TestAction& action = testActions[i];
            testResults.SetCurrentAction(&action);
            err = run_instrumentation_test(action.packageName, action.runner, action.className,
                    &testResults);
            check_error(err);
            if (action.passCount == 0 && action.failCount == 0) {
                action.target->actionsWithNoTests = true;
            }
            int total = action.passCount + action.failCount;
            printf("%sRan %d test%s for %s. ", g_escapeClearLine,
                    total, total > 1 ? "s" : "", action.target->name.c_str());
            if (action.passCount == 0 && action.failCount == 0) {
                printf("%s%d passed, %d failed%s\n", g_escapeYellowBold, action.passCount,
                        action.failCount, g_escapeEndColor);
            } else if (action.failCount >  0) {
                printf("%d passed, %s%d failed%s\n", action.passCount, g_escapeRedBold,
                        action.failCount, g_escapeEndColor);
            } else {
                printf("%s%d passed%s, %d failed\n", g_escapeGreenBold, action.passCount,
                        g_escapeEndColor, action.failCount);
            }
            if (!testResults.IsSuccess()) {
                printf("\n%sTest didn't finish successfully: %s%s\n", g_escapeRedBold,
                        testResults.GetErrorMessage().c_str(), g_escapeEndColor);
            }
        }
    }

    // Launch the activity
    if (activityActions.size() > 0) {
        print_status("Starting activity");

        if (activityActions.size() > 1) {
            print_warning("Multiple activities specified.  Will only start the first one:");
            for (size_t i=0; i<activityActions.size(); i++) {
                ActivityAction& action = activityActions[i];
                print_warning("   %s",
                        pretty_component_name(action.packageName, action.className).c_str());
            }
        }

        const ActivityAction& action = activityActions[0];
        string componentName = action.packageName + "/" + action.className;
        err = run_adb("shell", "am", "start", componentName.c_str(), NULL);
        check_error(err);
    }

    //
    // Print summary
    //

    printf("\n%s--------------------------------------------%s\n", g_escapeBold, g_escapeEndColor);

    // Build
    if (goals.size() > 0) {
        printf("%sBuilt:%s\n", g_escapeBold, g_escapeEndColor);
        for (size_t i=0; i<goals.size(); i++) {
            printf("   %s\n", goals[i].c_str());
        }
    }

    // Install
    if (syncSystem) {
        if (skipSync) {
            printf("%sSkipped syncing /system partition%s\n", g_escapeBold, g_escapeEndColor);
        } else {
            printf("%sSynced /system partition%s\n", g_escapeBold, g_escapeEndColor);
        }
    }
    if (installApks.size() > 0) {
        bool printedTitle = false;
        for (size_t i=0; i<installApks.size(); i++) {
            const InstallApk& apk = installApks[i];
            if (apk.installed) {
                if (!printedTitle) {
                    printf("%sInstalled:%s\n", g_escapeBold, g_escapeEndColor);
                    printedTitle = true;
                }
                printf("   %s\n", apk.file.filename.c_str());
            }
        }
        printedTitle = false;
        for (size_t i=0; i<installApks.size(); i++) {
            const InstallApk& apk = installApks[i];
            if (!apk.installed) {
                if (!printedTitle) {
                    printf("%sSkipped install:%s\n", g_escapeBold, g_escapeEndColor);
                    printedTitle = true;
                }
                printf("   %s\n", apk.file.filename.c_str());
            }
        }
    }

    // Tests
    bool hasErrors = false;
    if (testActions.size() > 0) {
        printf("%sRan tests:%s\n", g_escapeBold, g_escapeEndColor);
        size_t maxNameLength = 0;
        for (size_t i=0; i<targets.size(); i++) {
            Target* target = targets[i];
            if (target->test) {
                size_t len = target->name.length();
                if (len > maxNameLength) {
                    maxNameLength = len;
                }
            }
        }
        string padding(maxNameLength, ' ');
        for (size_t i=0; i<targets.size(); i++) {
            Target* target = targets[i];
            if (target->testActionCount > 0) {
                printf("   %s%s", target->name.c_str(), padding.c_str() + target->name.length());
                if (target->unknownFailureCount > 0) {
                    printf("     %sUnknown failure, see above message.%s\n",
                            g_escapeRedBold, g_escapeEndColor);
                    hasErrors = true;
                } else if (target->actionsWithNoTests) {
                    printf("     %s%d passed, %d failed%s\n", g_escapeYellowBold,
                            target->testPassCount, target->testFailCount, g_escapeEndColor);
                    hasErrors = true;
                } else if (target->testFailCount > 0) {
                    printf("     %d passed, %s%d failed%s\n", target->testPassCount,
                            g_escapeRedBold, target->testFailCount, g_escapeEndColor);
                    hasErrors = true;
                } else {
                    printf("     %s%d passed%s, %d failed\n", g_escapeGreenBold,
                            target->testPassCount, g_escapeEndColor, target->testFailCount);
                }
            }
        }
    }
    if (activityActions.size() > 1) {
        printf("%sStarted Activity:%s\n", g_escapeBold, g_escapeEndColor);
        const ActivityAction& action = activityActions[0];
        printf("   %s\n", pretty_component_name(action.packageName, action.className).c_str());
    }

    printf("%s--------------------------------------------%s\n", g_escapeBold, g_escapeEndColor);
    return !hasErrors;
}

/**
 * Implement tab completion of the target names from the all modules file.
 */
void
run_tab_completion(const string& word)
{
    const string buildTop = get_required_env("ANDROID_BUILD_TOP", true);
    const string buildProduct = get_required_env("TARGET_PRODUCT", false);
    const string buildOut = get_out_dir();

    chdir_or_exit(buildTop.c_str());

    string buildDevice = sniff_device_name(buildOut, buildProduct);

    map<string,Module> modules;
    read_modules(buildOut, buildDevice, &modules, true);

    for (map<string,Module>::const_iterator it = modules.begin(); it != modules.end(); it++) {
        if (starts_with(it->first, word)) {
            printf("%s\n", it->first.c_str());
        }
    }
}

/**
 * Main entry point.
 */
int
main(int argc, const char** argv)
{
    GOOGLE_PROTOBUF_VERIFY_VERSION;
    init_print();

    Options options;
    parse_args(&options, argc, argv);

    if (options.runHelp) {
        // Help
        print_usage(stdout);
        exit(0);
    } else if (options.runTab) {
        run_tab_completion(options.tabPattern);
        exit(0);
    } else {
        // Normal run
        exit(run_phases(options.targets, options) ? 0 : 1);
    }

    return 0;
}

