/*
 * dexopt invocation test.
 *
 * You must have BOOTCLASSPATH defined.  On the simulator, you will also
 * need ANDROID_ROOT.
 */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/file.h>
#include <fcntl.h>
#include <errno.h>

#include "cutils/properties.h"

//using namespace android;

/*
 * Privilege reduction function.
 *
 * Returns 0 on success, nonzero on failure.
 */
static int privFunc(void)
{
    printf("--- would reduce privs here\n");
    return 0;
}

/*
 * We're in the child process.  exec dexopt.
 */
static void runDexopt(int zipFd, int odexFd, const char* inputFileName)
{
    static const char* kDexOptBin = "/bin/dexopt";
    static const int kMaxIntLen = 12;   // '-'+10dig+'\0' -OR- 0x+8dig
    char zipNum[kMaxIntLen];
    char odexNum[kMaxIntLen];
    char dexoptFlags[PROPERTY_VALUE_MAX];
    const char* androidRoot;
    char* execFile;

    /* pull optional configuration tweaks out of properties */
    property_get("dalvik.vm.dexopt-flags", dexoptFlags, "");

    /* find dexopt executable; this exists for simulator compatibility */
    androidRoot = getenv("ANDROID_ROOT");
    if (androidRoot == NULL)
        androidRoot = "/system";
    execFile = (char*) malloc(strlen(androidRoot) + strlen(kDexOptBin) +1);
    sprintf(execFile, "%s%s", androidRoot, kDexOptBin);

    sprintf(zipNum, "%d", zipFd);
    sprintf(odexNum, "%d", odexFd);

    execl(execFile, execFile, "--zip", zipNum, odexNum, inputFileName,
        dexoptFlags, (char*) NULL);
    fprintf(stderr, "execl(%s) failed: %s\n", kDexOptBin, strerror(errno));
}

/*
 * Run dexopt on the specified Jar/APK.
 *
 * This uses fork() and exec() to mimic the way this would work in an
 * installer; in practice for something this simple you could just exec()
 * unless you really wanted the status messages.
 *
 * Returns 0 on success.
 */
int doStuff(const char* zipName, const char* odexName)
{
    int zipFd, odexFd;

    /*
     * Open the zip archive and the odex file, creating the latter (and
     * failing if it already exists).  This must be done while we still
     * have sufficient privileges to read the source file and create a file
     * in the target directory.  The "classes.dex" file will be extracted.
     */
    zipFd = open(zipName, O_RDONLY, 0);
    if (zipFd < 0) {
        fprintf(stderr, "Unable to open '%s': %s\n", zipName, strerror(errno));
        return 1;
    }

    odexFd = open(odexName, O_RDWR | O_CREAT | O_EXCL, 0644);
    if (odexFd < 0) {
        fprintf(stderr, "Unable to create '%s': %s\n",
            odexName, strerror(errno));
        close(zipFd);
        return 1;
    }

    printf("--- BEGIN '%s' (bootstrap=%d) ---\n", zipName, 0);

    /*
     * Fork a child process.
     */
    pid_t pid = fork();
    if (pid == 0) {
        /* child -- drop privs */
        if (privFunc() != 0)
            exit(66);

        /* lock the input file */
        if (flock(odexFd, LOCK_EX | LOCK_NB) != 0) {
            fprintf(stderr, "Unable to lock '%s': %s\n",
                odexName, strerror(errno));
            exit(65);
        }

        runDexopt(zipFd, odexFd, zipName);  /* does not return */
        exit(67);                           /* usually */
    } else {
        /* parent -- wait for child to finish */
        printf("--- waiting for verify+opt, pid=%d\n", (int) pid);
        int status, oldStatus;
        pid_t gotPid;

        close(zipFd);
        close(odexFd);

        /*
         * Wait for the optimization process to finish.
         */
        while (true) {
            gotPid = waitpid(pid, &status, 0);
            if (gotPid == -1 && errno == EINTR) {
                printf("waitpid interrupted, retrying\n");
            } else {
                break;
            }
        }
        if (gotPid != pid) {
            fprintf(stderr, "waitpid failed: wanted %d, got %d: %s\n",
                (int) pid, (int) gotPid, strerror(errno));
            return 1;
        }

        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
            printf("--- END '%s' (success) ---\n", zipName);
            return 0;
        } else {
            printf("--- END '%s' --- status=0x%04x, process failed\n",
                zipName, status);
            return 1;
        }
    }

    /* notreached */
}

/*
 * Parse args, do stuff.
 */
int main(int argc, char** argv)
{
    if (argc < 3 || argc > 4) {
        fprintf(stderr, "Usage: %s <input jar/apk> <output odex> "
            "[<bootclasspath>]\n\n", argv[0]);
        fprintf(stderr, "Example: dexopttest "
            "/system/app/NotePad.apk /system/app/NotePad.odex\n");
        return 2;
    }

    if (argc > 3) {
        setenv("BOOTCLASSPATH", argv[3], 1);
    }

    return (doStuff(argv[1], argv[2]) != 0);
}
