// Copyright ClockworkMod, LLC. Reference and porting purposes only. Usage of the extendedcommand API
// is restricted to those granted explicit permission, or by use of the ROM Manager Recovery API.
// https://github.com/koush/TestRomManager
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <limits.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/reboot.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <sys/wait.h>
#include <sys/limits.h>
#include <dirent.h>
#include <sys/stat.h>

#include <signal.h>
#include <sys/wait.h>

#include "bootloader.h"
#include "common.h"
#include "cutils/properties.h"
#include "firmware.h"
#include "install.h"
#include "minui/minui.h"
#include "minzip/DirUtil.h"
#include "roots.h"
#include "recovery_ui.h"

#include "../../external/yaffs2/yaffs2/utils/mkyaffs2image.h"
#include "../../external/yaffs2/yaffs2/utils/unyaffs.h"

#include "extendedcommands.h"
#include "nandroid.h"
#include "mounts.h"
#include "flashutils/flashutils.h"
#include "edify/expr.h"
#include "mtdutils/mtdutils.h"
#include "mmcutils/mmcutils.h"
//#include "edify/parser.h"

Value* UIPrintFn(const char* name, State* state, int argc, Expr* argv[]) {
    char** args = ReadVarArgs(state, argc, argv);
    if (args == NULL) {
        return NULL;
    }

    int size = 0;
    int i;
    for (i = 0; i < argc; ++i) {
        size += strlen(args[i]);
    }
    char* buffer = malloc(size+1);
    size = 0;
    for (i = 0; i < argc; ++i) {
        strcpy(buffer+size, args[i]);
        size += strlen(args[i]);
        free(args[i]);
    }
    free(args);
    buffer[size] = '\0';

    char* line = strtok(buffer, "\n");
    while (line) {
        ui_print("%s\n", line);
        line = strtok(NULL, "\n");
    }

    return StringValue(buffer);
}

Value* RunProgramFn(const char* name, State* state, int argc, Expr* argv[]) {
    if (argc < 1) {
        return ErrorAbort(state, "%s() expects at least 1 arg", name);
    }
    char** args = ReadVarArgs(state, argc, argv);
    if (args == NULL) {
        return NULL;
    }

    char** args2 = malloc(sizeof(char*) * (argc+1));
    memcpy(args2, args, sizeof(char*) * argc);
    args2[argc] = NULL;

    fprintf(stderr, "about to run program [%s] with %d args\n", args2[0], argc);

    pid_t child = fork();
    if (child == 0) {
        execv(args2[0], args2);
        fprintf(stderr, "run_program: execv failed: %s\n", strerror(errno));
        _exit(1);
    }
    int status;
    waitpid(child, &status, 0);
    if (WIFEXITED(status)) {
        if (WEXITSTATUS(status) != 0) {
            fprintf(stderr, "run_program: child exited with status %d\n",
                    WEXITSTATUS(status));
        }
    } else if (WIFSIGNALED(status)) {
        fprintf(stderr, "run_program: child terminated by signal %d\n",
                WTERMSIG(status));
    }

    int i;
    for (i = 0; i < argc; ++i) {
        free(args[i]);
    }
    free(args);
    free(args2);

    char buffer[20];
    sprintf(buffer, "%d", status);

    return StringValue(strdup(buffer));
}

Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) {
    char* result = NULL;
    if (argc != 1) {
        return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc);
    }
    
    char *path;
    if (ReadArgs(state, argv, 1, &path) < 0) {
        return NULL;
    }
    
    ui_print("Formatting %s...\n", path);
    if (0 != format_volume(path)) {
        free(path);
        return StringValue(strdup(""));
    }
    
    if (strcmp(path, "/data") == 0 && has_datadata()) {
        ui_print("Formatting /datadata...\n", path);
        if (0 != format_volume("/datadata")) {
            free(path);
            return StringValue(strdup(""));
        }
        if (0 != format_volume("/sdcard/.android_secure")) {
            free(path);
            return StringValue(strdup(""));
        }
    }

done:
    return StringValue(strdup(path));
}

Value* BackupFn(const char* name, State* state, int argc, Expr* argv[]) {
    char* result = NULL;
    if (argc != 1) {
        return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
    }
    char* path;
    if (ReadArgs(state, argv, 1, &path) < 0) {
        return NULL;
    }
    
    if (0 != nandroid_backup(path))
        return StringValue(strdup(""));
    
    return StringValue(strdup(path));
}

Value* RestoreFn(const char* name, State* state, int argc, Expr* argv[]) {
    if (argc < 1) {
        return ErrorAbort(state, "%s() expects at least 1 arg", name);
    }
    char** args = ReadVarArgs(state, argc, argv);
    if (args == NULL) {
        return NULL;
    }

    char** args2 = malloc(sizeof(char*) * (argc+1));
    memcpy(args2, args, sizeof(char*) * argc);
    args2[argc] = NULL;
    
    char* path = strdup(args2[0]);
    int restoreboot = 1;
    int restoresystem = 1;
    int restoredata = 1;
    int restorecache = 1;
    int restoresdext = 1;
    int i;
    for (i = 1; i < argc; i++)
    {
        if (args2[i] == NULL)
            continue;
        if (strcmp(args2[i], "noboot") == 0)
            restoreboot = 0;
        else if (strcmp(args2[i], "nosystem") == 0)
            restoresystem = 0;
        else if (strcmp(args2[i], "nodata") == 0)
            restoredata = 0;
        else if (strcmp(args2[i], "nocache") == 0)
            restorecache = 0;
        else if (strcmp(args2[i], "nosd-ext") == 0)
            restoresdext = 0;
    }
    
    for (i = 0; i < argc; ++i) {
        free(args[i]);
    }
    free(args);
    free(args2);

    if (0 != nandroid_restore(path, restoreboot, restoresystem, restoredata, restorecache, restoresdext, 0)) {
        free(path);
        return StringValue(strdup(""));
    }
    
    return StringValue(path);
}

Value* InstallZipFn(const char* name, State* state, int argc, Expr* argv[]) {
    char* result = NULL;
    if (argc != 1) {
        return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
    }
    char* path;
    if (ReadArgs(state, argv, 1, &path) < 0) {
        return NULL;
    }
    
    if (0 != install_zip(path))
        return StringValue(strdup(""));
    
    return StringValue(strdup(path));
}

Value* MountFn(const char* name, State* state, int argc, Expr* argv[]) {
    char* result = NULL;
    if (argc != 1) {
        return ErrorAbort(state, "%s() expects 1 args, got %d", name, argc);
    }
    char* path;
    if (ReadArgs(state, argv, 1, &path) < 0) {
        return NULL;
    }
    
    if (0 != ensure_path_mounted(path))
        return StringValue(strdup(""));

    return StringValue(strdup(path));
}

void RegisterRecoveryHooks() {
    RegisterFunction("mount", MountFn);
    RegisterFunction("format", FormatFn);
    RegisterFunction("ui_print", UIPrintFn);
    RegisterFunction("run_program", RunProgramFn);
    RegisterFunction("backup_rom", BackupFn);
    RegisterFunction("restore_rom", RestoreFn);
    RegisterFunction("install_zip", InstallZipFn);
}

static int hasInitializedEdify = 0;
int run_script_from_buffer(char* script_data, int script_len, char* filename)
{
    if (!hasInitializedEdify) {
        RegisterBuiltins();
        RegisterRecoveryHooks();
        FinishRegistration();
        hasInitializedEdify = 1;
    }

    Expr* root;
    int error_count = 0;
    yy_scan_bytes(script_data, script_len);
    int error = yyparse(&root, &error_count);
    printf("parse returned %d; %d errors encountered\n", error, error_count);
    if (error == 0 || error_count > 0) {
        //ExprDump(0, root, buffer);

        State state;
        state.cookie = NULL;
        state.script = script_data;
        state.errmsg = NULL;

        char* result = Evaluate(&state, root);
        if (result == NULL) {
            printf("result was NULL, message is: %s\n",
                   (state.errmsg == NULL ? "(NULL)" : state.errmsg));
            free(state.errmsg);
            return -1;
        } else {
            printf("result is [%s]\n", result);
        }
    }
    return 0;
}
