/*
 * Main entry of app process.
 *
 * Starts the interpreted runtime, then starts up the application.
 *
 */

#define LOG_TAG "appproc"

#include "stringprintf.h"
#include "logging.h"

#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <utils/Log.h>
#include <cutils/process_name.h>
#include <cutils/memory.h>
#include <android_runtime/AndroidRuntime.h>

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

namespace android {

void app_usage()
{
    fprintf(stderr,
        "Usage: oat_process [java-options] cmd-dir start-class-name [options]\n");
}

class AppRuntime : public AndroidRuntime
{
public:
    AppRuntime()
        : mParentDir(NULL)
        , mClassName(NULL)
        , mClass(NULL)
        , mArgC(0)
        , mArgV(NULL)
    {
    }

#if 0
    // this appears to be unused
    const char* getParentDir() const
    {
        return mParentDir;
    }
#endif

    const char* getClassName() const
    {
        return mClassName;
    }

    virtual void onVmCreated(JNIEnv* env)
    {
        if (mClassName == NULL) {
            return; // Zygote. Nothing to do here.
        }

        /*
         * This is a little awkward because the JNI FindClass call uses the
         * class loader associated with the native method we're executing in.
         * If called in onStarted (from RuntimeInit.finishInit because we're
         * launching "am", for example), FindClass would see that we're calling
         * from a boot class' native method, and so wouldn't look for the class
         * we're trying to look up in CLASSPATH. Unfortunately it needs to,
         * because the "am" classes are not boot classes.
         *
         * The easiest fix is to call FindClass here, early on before we start
         * executing boot class Java code and thereby deny ourselves access to
         * non-boot classes.
         */
        char* slashClassName = toSlashClassName(mClassName);
        mClass = env->FindClass(slashClassName);
        if (mClass == NULL) {
            LOG(FATAL) << "Could not find class: " << mClassName;
        }
        free(slashClassName);

        mClass = reinterpret_cast<jclass>(env->NewGlobalRef(mClass));
    }

    virtual void onStarted()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();

        AndroidRuntime* ar = AndroidRuntime::getRuntime();
        ar->callMain(mClassName, mClass, mArgC, mArgV);

        IPCThreadState::self()->stopProcess();
    }

    virtual void onZygoteInit()
    {
        sp<ProcessState> proc = ProcessState::self();
        ALOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }

    virtual void onExit(int code)
    {
        if (mClassName == NULL) {
            // if zygote
            IPCThreadState::self()->stopProcess();
        }

        AndroidRuntime::onExit(code);
    }


    const char* mParentDir;
    const char* mClassName;
    jclass mClass;
    int mArgC;
    const char* const* mArgV;
};

}

using namespace android;

/*
 * sets argv0 to as much of newArgv0 as will fit
 */
static void setArgv0(const char *argv0, const char *newArgv0)
{
    strlcpy(const_cast<char *>(argv0), newArgv0, strlen(argv0));
}

int main(int argc, const char* argv[])
{
    // These are global variables in ProcessState.cpp
    mArgC = argc;
    mArgV = argv;

    mArgLen = 0;
    for (int i=0; i<argc; i++) {
        mArgLen += strlen(argv[i]) + 1;
    }
    mArgLen--;

    AppRuntime runtime;
    const char* argv0 = argv[0];

    // Process command line arguments
    // ignore argv[0]
    argc--;
    argv++;

    // ignore /system/bin/app_process when invoked via WrapperInit
    if (strcmp(argv[0], "/system/bin/app_process") == 0) {
        LOG(INFO) << "Removing /system/bin/app_process argument";
        argc--;
        argv++;
        for (int i = 0; i < argc; i++) {
            LOG(INFO) << StringPrintf("argv[%d]=%s", i, argv[i]);
        }
    }

    // TODO: remove when we default the boot image
    int oatArgc = argc + 1;
    const char* oatArgv[oatArgc];
    if (strcmp(argv[0], "-Ximage:/data/art-cache/boot.art") != 0) {
        LOG(INFO) << "Adding image arguments";
        oatArgv[0] = "-Ximage:/data/art-cache/boot.art";
        memcpy(oatArgv + (oatArgc - argc), argv, argc * sizeof(*argv));
        argv = oatArgv;
        argc = oatArgc;
        for (int i = 0; i < argc; i++) {
            LOG(INFO) << StringPrintf("argv[%d]=%s", i, argv[i]);
        }
    }

    // TODO: remove the heap arguments when implicit garbage collection enabled
    LOG(INFO) << "Adding heap arguments";
    int heapArgc = argc + 2;
    const char* heapArgv[heapArgc];
    heapArgv[0] = "-Xms64m";
    heapArgv[1] = "-Xmx64m";
    memcpy(heapArgv + (heapArgc - argc), argv, argc * sizeof(*argv));
    argv = heapArgv;
    argc = heapArgc;
    for (int i = 0; i < argc; i++) {
        LOG(INFO) << StringPrintf("argv[%d]=%s", i, argv[i]);
    }

    // TODO: change the system default to not perform preloading
    LOG(INFO) << "Disabling preloading";
    for (int i = 0; i < argc; i++) {
        if (strcmp(argv[i], "preload") == 0) {
            argv[i] = "nopreload";
            break;
        }
    }
    for (int i = 0; i < argc; i++) {
        LOG(INFO) << StringPrintf("argv[%d]=%s", i, argv[i]);
    }

    // Everything up to '--' or first non '-' arg goes to the vm

    int i = runtime.addVmArguments(argc, argv);

    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    bool noPreload = false;
    bool application = false;
    const char* parentDir = NULL;
    const char* niceName = NULL;
    const char* className = NULL;
    while (i < argc) {
        const char* arg = argv[i++];
        if (!parentDir) {
            parentDir = arg;
        } else if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = "zygote";
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else if (strcmp(arg, "--no-preload") == 0) {
            noPreload = true;
        } else if (strcmp(arg, "--application") == 0) {
            application = true;
        } else if (strncmp(arg, "--nice-name=", 12) == 0) {
            niceName = arg + 12;
        } else {
            className = arg;
            break;
        }
    }

    if (niceName && *niceName) {
        setArgv0(argv0, niceName);
        set_process_name(niceName);
    }

    runtime.mParentDir = parentDir;

    if (zygote) {
        std::string options;
        if (startSystemServer) {
            options += "start-system-server ";
        }
        if (noPreload) {
            options += "no-preload ";
        }
        runtime.start("com.android.internal.os.ZygoteInit", options.c_str());
    } else if (className) {
        // Remainder of args get passed to startup class main()
        runtime.mClassName = className;
        runtime.mArgC = argc - i;
        runtime.mArgV = argv + i;
        runtime.start("com.android.internal.os.RuntimeInit",
                application ? "application" : "tool");
    } else {
        fprintf(stderr, "Error: no class name or --zygote supplied.\n");
        app_usage();
        LOG(FATAL) << "oat_process: no class name or --zygote supplied.";
        return 10;
    }
}
