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

#define NATIVE_TESTS "NATIVE_TESTS"

/**
 * 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 testIgnoreCount;
    int unknownFailureCount; // unknown failure == "Process crashed", etc.

    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),
        testIgnoreCount(0),
        unknownFailureCount(0) {}

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

    // For refreshing module-info.json
    bool runRefresh;

    // For tab completion
    bool runTab;
    string tabPattern;

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

    Options();
    ~Options();
};

Options::Options()
    :runHelp(false),
     runRefresh(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)
{
}

struct PushedFile
{
    TrackedFile file;
    string dest;

    PushedFile();
    PushedFile(const PushedFile& that);
    PushedFile(const string& filename, const string& dest);
    ~PushedFile() {};
};

PushedFile::PushedFile()
{
}

PushedFile::PushedFile(const PushedFile& that)
    :file(that.file),
     dest(that.dest)
{
}

PushedFile::PushedFile(const string& f, const string& d)
    :file(f),
     dest(d)
{
}

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

    // The number of tests that were ignored (because of @Ignore)
    int ignoreCount;
};

TestAction::TestAction() : passCount(0), failCount(0), ignoreCount(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);

        bool stackFound;
        string stack = get_bundle_string(results, &stackFound, "stack", NULL);
        if (status.has_logcat()) {
            const string logcat = status.logcat();
            if (logcat.length() > 0) {
                printf("%s\n", logcat.c_str());
            }
        } else if (stackFound) {
            printf("%s\n", stack.c_str());
        }
    } else if (resultCode == -3) {
        // test ignored
        m_currentAction->ignoreCount++;
        m_currentAction->target->testIgnoreCount++;
        printf("%s\n%sIgnored: %s:%s#%s%s\n", g_escapeClearLine, g_escapeYellowBold,
               m_currentAction->target->name.c_str(), className.c_str(), testName.c_str(),
               g_escapeEndColor);
    }
}

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 --refresh\n");
    fprintf(out, "\n");
    fprintf(out, "  Update module-info.json, the cache of make goals that can be built.\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");
}

/**
 * Prints a possibly color-coded summary of test results. Example output:
 *
 *     "34 passed, 0 failed, 1 ignored\n"
 */
static void print_results(int passed, int failed, int ignored) {
    char const* nothing = "";
    char const* cp = nothing;
    char const* cf = nothing;
    char const* ci = nothing;

    if (failed > 0) {
        cf = g_escapeRedBold;
    } else if (passed > 0 || ignored > 0) {
        cp = passed > 0 ? g_escapeGreenBold : nothing;
        ci = ignored > 0 ? g_escapeYellowBold : nothing;
    } else {
        cp = g_escapeYellowBold;
        cf = g_escapeYellowBold;
    }

    if (ignored > 0) {
        printf("%s%d passed%s, %s%d failed%s, %s%d ignored%s\n", cp, passed, g_escapeEndColor, cf,
               failed, g_escapeEndColor, ci, ignored, g_escapeEndColor);
    } else {
        printf("%s%d passed%s, %s%d failed%s\n", cp, passed, g_escapeEndColor, cf, failed,
               g_escapeEndColor);
    }
}

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

    // Refresh
    if (argc == 2 && strcmp(argv[1], "--refresh") == 0) {
        options->runRefresh = 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);
    const string buildOut = get_out_dir();
    chdir_or_exit(buildTop.c_str());

    BuildVars buildVars(buildOut, buildProduct, buildVariant, buildType);

    const string buildDevice = buildVars.GetBuildVar("TARGET_DEVICE", false);
    const string buildId = buildVars.GetBuildVar("BUILD_ID", false);

    // 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());
            fprintf(stderr, "Try running %sbit --refresh%s if you recently added %s%s%s.\n",
                    g_escapeBold, g_escapeEndColor,
                    g_escapeBold, target->name.c_str(), g_escapeEndColor);
            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 deviceTargetPath = buildOut + "/target/product/" + buildDevice;
    string systemPath = deviceTargetPath + "/system/";
    string dataPath = deviceTargetPath + "/data/";
    string testPath = deviceTargetPath + "/testcases/";
    bool syncSystem = false;
    bool alwaysSyncSystem = false;
    vector<string> systemFiles;
    vector<InstallApk> installApks;
    vector<PushedFile> pushedFiles;
    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;
                    systemFiles.push_back(file);
                    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 (ends_with(file, ".apk")
                        && (starts_with(file, dataPath) || starts_with(file, testPath))) {
                    // Always install it if we didn't build it because otherwise
                    // it will never have changed.
                    installApks.push_back(InstallApk(file, !target->build));
                    continue;
                }
                // If it's a native test module, push it.
                if (target->module.HasClass(NATIVE_TESTS) && starts_with(file, dataPath)) {
                    string installedPath(file.c_str() + deviceTargetPath.length());
                    pushedFiles.push_back(PushedFile(file, installedPath));
                }
            }
        }
    }
    map<string,FileInfo> systemFilesBefore;
    if (syncSystem && !alwaysSyncSystem) {
        get_directory_contents(systemPath, &systemFilesBefore);
    }

    if (systemFiles.size() > 0){
        print_info("System files:");
        for (size_t i=0; i<systemFiles.size(); i++) {
            printf("  %s\n", systemFiles[i].c_str());
        }
    }
    if (pushedFiles.size() > 0){
        print_info("Files to push:");
        for (size_t i=0; i<pushedFiles.size(); i++) {
            printf("  %s\n", pushedFiles[i].file.filename.c_str());
            printf("    --> %s\n", pushedFiles[i].dest.c_str());
        }
    }
    if (installApks.size() > 0){
        print_info("APKs to install:");
        for (size_t i=0; i<installApks.size(); i++) {
            printf("  %s\n", installApks[i].file.filename.c_str());
        }
    }

    //
    // 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("exec-out", "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("exec-out", "setprop", "sys.boot_completed", "0", NULL);
                    check_error(err);
                    err = run_adb("exec-out", "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("exec-out", "wm", "dismiss-keyguard", NULL);
                check_error(err);
            }
        }
    }

    // Push files
    if (pushedFiles.size() > 0) {
        print_status("Pushing files");
        for (size_t i=0; i<pushedFiles.size(); i++) {
            const PushedFile& pushed = pushedFiles[i];
            string dir = dirname(pushed.dest);
            if (dir.length() == 0 || dir == "/") {
                // This isn't really a file inside the data directory. Just skip it.
                continue;
            }
            // TODO: if (!apk.file.fileInfo.exists || apk.file.HasChanged())
            err = run_adb("exec-out", "mkdir", "-p", dir.c_str(), NULL);
            check_error(err);
            err = run_adb("push", pushed.file.filename.c_str(), pushed.dest.c_str(), NULL);
            check_error(err);
            // pushed.installed = true;
        }
    }

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

    // Whether there have been any tests run, so we can print a summary.
    bool testsRun = false;

    // Run the native tests.
    // TODO: We don't have a good way of running these and capturing the output of
    // them live.  It'll take some work.  On the other hand, if they're gtest tests,
    // the output of gtest is not completely insane like the text output of the
    // instrumentation tests.  So for now, we'll just live with that.
    for (size_t i=0; i<targets.size(); i++) {
        Target* target = targets[i];
        if (target->test && target->module.HasClass(NATIVE_TESTS)) {
            // We don't have a clear signal from the build system which of the installed
            // files is actually the test, so we guess by looking for one with the same
            // leaf name as the module that is executable.
            for (size_t j=0; j<target->module.installed.size(); j++) {
                string filename = target->module.installed[j];
                if (!starts_with(filename, dataPath)) {
                    // Native tests go into the data directory.
                    continue;
                }
                if (leafname(filename) != target->module.name) {
                    // This isn't the test executable.
                    continue;
                }
                if (!is_executable(filename)) {
                    continue;
                }
                string installedPath(filename.c_str() + deviceTargetPath.length());
                printf("the magic one is: %s\n", filename.c_str());
                printf("  and it's installed at: %s\n", installedPath.c_str());

                // Convert bit-style actions to gtest test filter arguments
                if (target->actions.size() > 0) {
                    testsRun = true;
                    target->testActionCount++;
                    bool runAll = false;
                    string filterArg("--gtest_filter=");
                    for (size_t k=0; k<target->actions.size(); k++) {
                        string actionString = target->actions[k];
                        if (actionString == "*") {
                            runAll = true;
                        } else {
                            filterArg += actionString;
                            if (k != target->actions.size()-1) {
                                // We would otherwise have to worry about this condition
                                // being true, and appending an extra ':', but we know that
                                // if the extra action is "*", then we'll just run all and
                                // won't use filterArg anyway, so just keep this condition
                                // simple.
                                filterArg += ':';
                            }
                        }
                    }
                    if (runAll) {
                        err = run_adb("exec-out", installedPath.c_str(), NULL);
                    } else {
                        err = run_adb("exec-out", installedPath.c_str(), filterArg.c_str(), NULL);
                    }
                    if (err == 0) {
                        target->testPassCount++;
                    } else {
                        target->testFailCount++;
                    }
                }
            }
        }
    }

    // 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];

                // Skip of not apk in the data partition or test
                if (!(ends_with(filename, ".apk")
                        && (starts_with(filename, dataPath) || starts_with(filename, testPath)))) {
                    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");
        testsRun = true;
        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);
            int total = action.passCount + action.failCount;
            printf("%sRan %d test%s for %s. ", g_escapeClearLine,
                    total, total > 1 ? "s" : "", action.target->name.c_str());
            print_results(action.passCount, action.failCount, action.ignoreCount);
            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("exec-out", "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 (testsRun) {
        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 {
                    printf("   %s%s     ", target->name.c_str(),
                           padding.c_str() + target->name.length());
                    print_results(target->testPassCount, target->testFailCount,
                                  target->testIgnoreCount);
                }
            }
        }
    }
    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;
}

/**
 * Refresh module-info.
 */
void
run_refresh()
{
    int err;

    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);
    const string buildOut = get_out_dir();
    chdir_or_exit(buildTop.c_str());

    BuildVars buildVars(buildOut, buildProduct, buildVariant, buildType);

    string buildDevice = buildVars.GetBuildVar("TARGET_DEVICE", false);

    vector<string> goals;
    goals.push_back(buildOut + "/target/product/" + buildDevice + "/module-info.json");

    print_status("Refreshing module-info.json");
    err = build_goals(goals);
    check_error(err);
}

/**
 * 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", 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);
    const string buildOut = get_out_dir();
    chdir_or_exit(buildTop.c_str());

    BuildVars buildVars(buildOut, buildProduct, buildVariant, buildType);

    string buildDevice = buildVars.GetBuildVar("TARGET_DEVICE", false);

    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.runRefresh) {
        run_refresh();
        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;
}

