// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2008-2009 Travis Geiselbrecht
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <lib/console.h>

#include <assert.h>
#include <ctype.h>
#include <debug.h>
#include <err.h>
#include <kernel/cmdline.h>
#include <kernel/mutex.h>
#include <kernel/thread.h>
#include <lk/init.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <trace.h>
#include <zircon/compiler.h>
#include <zircon/types.h>

#ifndef CONSOLE_ENABLE_HISTORY
#define CONSOLE_ENABLE_HISTORY 1
#endif

#define LINE_LEN 128

#define PANIC_LINE_LEN 32

#define MAX_NUM_ARGS 16

#define HISTORY_LEN 16

#define LOCAL_TRACE 0

#define WHITESPACE " \t"

/* debug buffer */
static char* debug_buffer;

/* echo commands? */
static bool echo = true;

/* command processor state */
static mutex_t command_lock = MUTEX_INITIAL_VALUE(command_lock);
int lastresult;
static bool abort_script;

#if CONSOLE_ENABLE_HISTORY
/* command history stuff */
static char* history; // HISTORY_LEN rows of LINE_LEN chars a piece
static uint history_next;

static void init_history(void);
static void add_history(const char* line);
static uint start_history_cursor(void);
static const char* next_history(uint* cursor);
static const char* prev_history(uint* cursor);
static void dump_history(void);
#endif

// A linear array of statically defined commands.
extern const cmd __start_commands[];
extern const cmd __stop_commands[];

static int cmd_help(int argc, const cmd_args* argv, uint32_t flags);
static int cmd_echo(int argc, const cmd_args* argv, uint32_t flags);
static int cmd_test(int argc, const cmd_args* argv, uint32_t flags);
#if CONSOLE_ENABLE_HISTORY
static int cmd_history(int argc, const cmd_args* argv, uint32_t flags);
#endif

STATIC_COMMAND_START
STATIC_COMMAND_MASKED("help", "this list", &cmd_help, CMD_AVAIL_ALWAYS)
STATIC_COMMAND_MASKED("echo", NULL, &cmd_echo, CMD_AVAIL_ALWAYS)
#if LK_DEBUGLEVEL > 1
STATIC_COMMAND_MASKED("test", "test the command processor", &cmd_test, CMD_AVAIL_ALWAYS)
#if CONSOLE_ENABLE_HISTORY
STATIC_COMMAND_MASKED("history", "command history", &cmd_history, CMD_AVAIL_ALWAYS)
#endif
#endif
STATIC_COMMAND_END(help);

static void console_init(uint level) {
#if CONSOLE_ENABLE_HISTORY
    init_history();
#endif
}

LK_INIT_HOOK(console, console_init, LK_INIT_LEVEL_HEAP);

#if CONSOLE_ENABLE_HISTORY
static int cmd_history(int argc, const cmd_args* argv, uint32_t flags) {
    dump_history();
    return 0;
}

static inline char* history_line(uint line) {
    return history + line * LINE_LEN;
}

static inline uint ptrnext(uint ptr) {
    return (ptr + 1) % HISTORY_LEN;
}

static inline uint ptrprev(uint ptr) {
    return (ptr - 1) % HISTORY_LEN;
}

static void dump_history(void) {
    printf("command history:\n");
    uint ptr = ptrprev(history_next);
    int i;
    for (i = 0; i < HISTORY_LEN; i++) {
        if (history_line(ptr)[0] != 0)
            printf("\t%s\n", history_line(ptr));
        ptr = ptrprev(ptr);
    }
}

static void init_history(void) {
    /* allocate and set up the history buffer */
    history = static_cast<char*>(calloc(1, HISTORY_LEN * LINE_LEN));
    history_next = 0;
}

static void add_history(const char* line) {
    // reject some stuff
    if (line[0] == 0)
        return;

    uint last = ptrprev(history_next);
    if (strcmp(line, history_line(last)) == 0)
        return;

    strlcpy(history_line(history_next), line, LINE_LEN);
    history_next = ptrnext(history_next);
}

static uint start_history_cursor(void) {
    return ptrprev(history_next);
}

static const char* next_history(uint* cursor) {
    uint i = ptrnext(*cursor);

    if (i == history_next)
        return ""; // can't let the cursor hit the head

    *cursor = i;
    return history_line(i);
}

static const char* prev_history(uint* cursor) {
    uint i;
    const char* str = history_line(*cursor);

    /* if we are already at head, stop here */
    if (*cursor == history_next)
        return str;

    /* back up one */
    i = ptrprev(*cursor);

    /* if the next one is gonna be null */
    if (history_line(i)[0] == '\0')
        return str;

    /* update the cursor */
    *cursor = i;
    return str;
}
#endif

static const cmd* match_command(const char* command, const uint8_t availability_mask) {
    for (const cmd* curr_cmd = __start_commands;
         curr_cmd != __stop_commands;
         ++curr_cmd) {
        if ((availability_mask & curr_cmd->availability_mask) != 0 &&
            strcmp(command, curr_cmd->cmd_str) == 0) {
            return curr_cmd;
        }
    }
    return NULL;
}

static inline int cgetchar(void) {
    char c;
    int r = platform_dgetc(&c, true);
    return (r < 0) ? r : c;
}
static inline void cputchar(char c) {
    platform_dputc(c);
}
static inline void cputs(const char* s) {
    platform_dputs_thread(s, strlen(s));
}

static int read_debug_line(const char** outbuffer, void* cookie) {
    size_t pos = 0;
    int escape_level = 0;
#if CONSOLE_ENABLE_HISTORY
    uint history_cursor = start_history_cursor();
#endif

    char* buffer = debug_buffer;

    for (;;) {
        /* loop until we get a char */
        int ci;
        if ((ci = cgetchar()) < 0)
            continue;

        char c = static_cast<char>(ci);

        //      TRACEF("c = 0x%hhx\n", c);

        if (escape_level == 0) {
            switch (c) {
            case '\r':
            case '\n':
                if (echo)
                    cputchar('\n');
                goto done;

            case 0x7f: // backspace or delete
            case 0x8:
                if (pos > 0) {
                    pos--;
                    cputs("\b \b"); // wipe out a character
                }
                break;

            case 0x1b: // escape
                escape_level++;
                break;

            default:
                buffer[pos++] = c;
                if (echo)
                    cputchar(c);
            }
        } else if (escape_level == 1) {
            // inside an escape, look for '['
            if (c == '[') {
                escape_level++;
            } else {
                // we didn't get it, abort
                escape_level = 0;
            }
        } else { // escape_level > 1
            switch (c) {
            case 67: // right arrow
                buffer[pos++] = ' ';
                if (echo)
                    cputchar(' ');
                break;
            case 68: // left arrow
                if (pos > 0) {
                    pos--;
                    if (echo) {
                        cputs("\b \b"); // wipe out a character
                    }
                }
                break;
#if CONSOLE_ENABLE_HISTORY
            case 65: // up arrow -- previous history
            case 66: // down arrow -- next history
                // wipe out the current line
                while (pos > 0) {
                    pos--;
                    if (echo) {
                        cputs("\b \b"); // wipe out a character
                    }
                }

                if (c == 65)
                    strlcpy(buffer, prev_history(&history_cursor), LINE_LEN);
                else
                    strlcpy(buffer, next_history(&history_cursor), LINE_LEN);
                pos = strlen(buffer);
                if (echo)
                    cputs(buffer);
                break;
#endif
            default:
                break;
            }
            escape_level = 0;
        }

        /* end of line. */
        if (pos == (LINE_LEN - 1)) {
            cputs("\nerror: line too long\n");
            pos = 0;
            goto done;
        }
    }

done:
    //  dprintf("returning pos %d\n", pos);

    // null terminate
    buffer[pos] = 0;

#if CONSOLE_ENABLE_HISTORY
    // add to history
    add_history(buffer);
#endif

    // return a pointer to our buffer
    *outbuffer = buffer;

    return static_cast<int>(pos);
}

static int tokenize_command(const char* inbuffer, const char** continuebuffer,
                            char* buffer, size_t buflen, cmd_args* args, int arg_count) {
    size_t inpos;
    size_t outpos;
    int arg;
    enum {
        INITIAL = 0,
        NEXT_FIELD,
        SPACE,
        IN_SPACE,
        TOKEN,
        IN_TOKEN,
        QUOTED_TOKEN,
        IN_QUOTED_TOKEN,
        VAR,
        IN_VAR,
        COMMAND_SEP,
    } state;
    char varname[128];
    size_t varnamepos;

    inpos = 0;
    outpos = 0;
    arg = 0;
    varnamepos = 0;
    state = INITIAL;
    *continuebuffer = NULL;

    for (;;) {
        char c = inbuffer[inpos];

        //      dprintf(SPEW, "c 0x%hhx state %d arg %d inpos %zu pos %zu\n", c, state, arg, inpos, outpos);

        switch (state) {
        case INITIAL:
        case NEXT_FIELD:
            if (c == '\0')
                goto done;
            if (isspace(c))
                state = SPACE;
            else if (c == ';')
                state = COMMAND_SEP;
            else
                state = TOKEN;
            break;
        case SPACE:
            state = IN_SPACE;
            break;
        case IN_SPACE:
            if (c == '\0')
                goto done;
            if (c == ';') {
                state = COMMAND_SEP;
            } else if (!isspace(c)) {
                state = TOKEN;
            } else {
                inpos++; // consume the space
            }
            break;
        case TOKEN:
            // start of a token
            DEBUG_ASSERT(c != '\0');
            if (c == '"') {
                // start of a quoted token
                state = QUOTED_TOKEN;
            } else if (c == '$') {
                // start of a variable
                state = VAR;
            } else {
                // regular, unquoted token
                state = IN_TOKEN;
                args[arg].str = &buffer[outpos];
            }
            break;
        case IN_TOKEN:
            if (c == '\0') {
                arg++;
                goto done;
            }
            if (isspace(c) || c == ';') {
                arg++;
                buffer[outpos] = 0;
                outpos++;
                /* are we out of tokens? */
                if (arg == arg_count)
                    goto done;
                state = NEXT_FIELD;
            } else {
                buffer[outpos] = c;
                outpos++;
                inpos++;
            }
            break;
        case QUOTED_TOKEN:
            // start of a quoted token
            DEBUG_ASSERT(c == '"');

            state = IN_QUOTED_TOKEN;
            args[arg].str = &buffer[outpos];
            inpos++; // consume the quote
            break;
        case IN_QUOTED_TOKEN:
            if (c == '\0') {
                arg++;
                goto done;
            }
            if (c == '"') {
                arg++;
                buffer[outpos] = 0;
                outpos++;
                /* are we out of tokens? */
                if (arg == arg_count)
                    goto done;

                state = NEXT_FIELD;
            }
            buffer[outpos] = c;
            outpos++;
            inpos++;
            break;
        case VAR:
            DEBUG_ASSERT(c == '$');

            state = IN_VAR;
            args[arg].str = &buffer[outpos];
            inpos++; // consume the dollar sign

            // initialize the place to store the variable name
            varnamepos = 0;
            break;
        case IN_VAR:
            if (c == '\0' || isspace(c) || c == ';') {
                // hit the end of variable, look it up and stick it inline
                varname[varnamepos] = 0;
#if WITH_LIB_ENV
                int rc = env_get(varname, &buffer[outpos], buflen - outpos);
#else
                (void)varname[0]; // nuke a warning
                int rc = -1;
#endif
                if (rc < 0) {
                    buffer[outpos++] = '0';
                    buffer[outpos++] = 0;
                } else {
                    outpos += strlen(&buffer[outpos]) + 1;
                }
                arg++;
                /* are we out of tokens? */
                if (arg == arg_count)
                    goto done;

                state = NEXT_FIELD;
            } else {
                varname[varnamepos] = c;
                varnamepos++;
                inpos++;
            }
            break;
        case COMMAND_SEP:
            // we hit a ;, so terminate the command and pass the remainder of the command back in continuebuffer
            DEBUG_ASSERT(c == ';');

            inpos++; // consume the ';'
            *continuebuffer = &inbuffer[inpos];
            goto done;
        }
    }

done:
    buffer[outpos] = 0;
    return arg;
}

static void convert_args(int argc, cmd_args* argv) {
    int i;

    for (i = 0; i < argc; i++) {
        unsigned long u = atoul(argv[i].str);
        argv[i].u = u;
        argv[i].p = (void*)u;
        argv[i].i = atol(argv[i].str);

        if (!strcmp(argv[i].str, "true") || !strcmp(argv[i].str, "on")) {
            argv[i].b = true;
        } else if (!strcmp(argv[i].str, "false") || !strcmp(argv[i].str, "off")) {
            argv[i].b = false;
        } else {
            argv[i].b = (argv[i].u == 0) ? false : true;
        }
    }
}

static zx_status_t command_loop(int (*get_line)(const char**, void*),
                                void* get_line_cookie, bool showprompt,
                                bool locked) TA_NO_THREAD_SAFETY_ANALYSIS {
    bool exit;
#if WITH_LIB_ENV
    bool report_result;
#endif
    cmd_args* args = NULL;
    const char* buffer;
    const char* continuebuffer;
    char* outbuf = NULL;

    args = (cmd_args*)malloc(MAX_NUM_ARGS * sizeof(cmd_args));
    if (unlikely(args == NULL)) {
        return ZX_ERR_NO_MEMORY;
    }

    const size_t outbuflen = 1024;
    outbuf = static_cast<char*>(malloc(outbuflen));
    if (unlikely(outbuf == NULL)) {
        free(args);
        return ZX_ERR_NO_MEMORY;
    }

    exit = false;
    continuebuffer = NULL;
    while (!exit) {
        // read a new line if it hadn't been split previously and passed back from tokenize_command
        if (continuebuffer == NULL) {
            if (showprompt)
                cputs("] ");

            int len = get_line(&buffer, get_line_cookie);
            if (len < 0)
                break;
            if (len == 0)
                continue;
        } else {
            buffer = continuebuffer;
        }

        //      dprintf("line = '%s'\n", buffer);

        /* tokenize the line */
        int argc = tokenize_command(buffer, &continuebuffer, outbuf, outbuflen,
                                    args, MAX_NUM_ARGS);
        if (argc < 0) {
            if (showprompt)
                printf("syntax error\n");
            continue;
        } else if (argc == 0) {
            continue;
        }

        //      dprintf("after tokenize: argc %d\n", argc);
        //      for (int i = 0; i < argc; i++)
        //          dprintf("%d: '%s'\n", i, args[i].str);

        /* convert the args */
        convert_args(argc, args);

        /* try to match the command */
        const cmd* command = match_command(args[0].str, CMD_AVAIL_NORMAL);
        if (!command) {
            printf("command \"%s\" not found\n", args[0].str);
            continue;
        }

        if (!locked)
            mutex_acquire(&command_lock);

        abort_script = false;
        lastresult = command->cmd_callback(argc, args, 0);

#if WITH_LIB_ENV
        bool report_result;
        env_get_bool("reportresult", &report_result, false);
        if (report_result) {
            if (lastresult < 0)
                printf("FAIL %d\n", lastresult);
            else
                printf("PASS %d\n", lastresult);
        }
#endif

#if WITH_LIB_ENV
        // stuff the result in an environment var
        env_set_int("?", lastresult, true);
#endif

        // someone must have aborted the current script
        if (abort_script)
            exit = true;
        abort_script = false;

        if (!locked)
            mutex_release(&command_lock);
    }

    free(outbuf);
    free(args);
    return ZX_OK;
}

void console_abort_script(void) {
    abort_script = true;
}

static void console_start(void) {
    debug_buffer = static_cast<char*>(malloc(LINE_LEN));

    dprintf(INFO, "entering main console loop\n");

    while (command_loop(&read_debug_line, NULL, true, false) == ZX_OK)
        ;

    dprintf(INFO, "exiting main console loop\n");

    free(debug_buffer);
}

struct line_read_struct {
    const char* string;
    int pos;
    char* buffer;
    size_t buflen;
};

static int fetch_next_line(const char** buffer, void* cookie) {
    struct line_read_struct* lineread = (struct line_read_struct*)cookie;

    // we're done
    if (lineread->string[lineread->pos] == 0)
        return -1;

    size_t bufpos = 0;
    while (lineread->string[lineread->pos] != 0) {
        if (lineread->string[lineread->pos] == '\n') {
            lineread->pos++;
            break;
        }
        if (bufpos == (lineread->buflen - 1))
            break;
        lineread->buffer[bufpos] = lineread->string[lineread->pos];
        lineread->pos++;
        bufpos++;
    }
    lineread->buffer[bufpos] = 0;

    *buffer = lineread->buffer;

    return static_cast<int>(bufpos);
}

static int console_run_script_etc(const char* string, bool locked) {
    struct line_read_struct lineread;

    lineread.string = string;
    lineread.pos = 0;
    lineread.buffer = static_cast<char*>(malloc(LINE_LEN));
    lineread.buflen = LINE_LEN;

    command_loop(&fetch_next_line, (void*)&lineread, false, locked);

    free(lineread.buffer);

    return lastresult;
}

int console_run_script(const char* string) {
    return console_run_script_etc(string, false);
}

int console_run_script_locked(const char* string) {
    return console_run_script_etc(string, true);
}

console_cmd* console_get_command_handler(const char* commandstr) {
    const cmd* command = match_command(commandstr, CMD_AVAIL_NORMAL);

    if (command)
        return command->cmd_callback;
    else
        return NULL;
}

static int cmd_help(int argc, const cmd_args* argv, uint32_t flags) {
    printf("command list:\n");

    /* filter out commands based on if we're called at normal or panic time */
    uint8_t availability_mask = (flags & CMD_FLAG_PANIC) ? CMD_AVAIL_PANIC : CMD_AVAIL_NORMAL;

    for (const cmd* curr_cmd = __start_commands;
         curr_cmd != __stop_commands;
         ++curr_cmd) {
        if ((availability_mask & curr_cmd->availability_mask) == 0) {
            // Skip commands that aren't available in the current shell.
            continue;
        }
        if (curr_cmd->help_str)
            printf("\t%-16s: %s\n", curr_cmd->cmd_str, curr_cmd->help_str);
    }

    return 0;
}

static int cmd_echo(int argc, const cmd_args* argv, uint32_t flags) {
    if (argc > 1)
        echo = argv[1].b;
    return ZX_OK;
}

static void panic_putc(char c) {
    platform_pputc(c);
}

static void panic_puts(const char* str) {
    for (;;) {
        char c = *str++;
        if (c == 0) {
            break;
        }
        platform_pputc(c);
    }
}

static int panic_getc(void) {
    char c;
    if (platform_pgetc(&c, false) < 0) {
        return -1;
    } else {
        return c;
    }
}

static void read_line_panic(char* buffer, const size_t len) {
    size_t pos = 0;

    for (;;) {
        int ci;
        if ((ci = panic_getc()) < 0) {
            continue;
        }

        char c = static_cast<char>(ci);

        switch (c) {
        case '\r':
        case '\n':
            panic_putc('\n');
            goto done;
        case 0x7f: // backspace or delete
        case 0x8:
            if (pos > 0) {
                pos--;
                panic_puts("\b \b"); // wipe out a character
            }
            break;
        default:
            buffer[pos++] = c;
            panic_putc(c);
        }
        if (pos == (len - 1)) {
            panic_puts("\nerror: line too long\n");
            pos = 0;
            goto done;
        }
    }
done:
    buffer[pos] = 0;
}

void panic_shell_start(void) {
    dprintf(INFO, "entering panic shell loop\n");
    char input_buffer[PANIC_LINE_LEN];
    cmd_args args[MAX_NUM_ARGS];

    for (;;) {
        panic_puts("! ");
        read_line_panic(input_buffer, PANIC_LINE_LEN);

        int argc;
        char* tok = strtok(input_buffer, WHITESPACE);
        for (argc = 0; argc < MAX_NUM_ARGS; argc++) {
            if (tok == NULL) {
                break;
            }
            args[argc].str = tok;
            tok = strtok(NULL, WHITESPACE);
        }

        if (argc == 0) {
            continue;
        }

        convert_args(argc, args);

        const cmd* command = match_command(args[0].str, CMD_AVAIL_PANIC);
        if (!command) {
            panic_puts("command not found\n");
            continue;
        }

        command->cmd_callback(argc, args, CMD_FLAG_PANIC);
    }
}

#if LK_DEBUGLEVEL > 1
static int cmd_test(int argc, const cmd_args* argv, uint32_t flags) {
    int i;

    printf("argc %d, argv %p\n", argc, argv);
    for (i = 0; i < argc; i++)
        printf("\t%d: str '%s', i %ld, u %#lx, p %p, b %d\n", i,
               argv[i].str, argv[i].i, argv[i].u, argv[i].p, argv[i].b);

    return 0;
}
#endif

static void kernel_shell_init(uint level) {
    if (cmdline_get_bool("kernel.shell", false)) {
        console_start();
    }
}

LK_INIT_HOOK(kernel_shell, kernel_shell_init, LK_INIT_LEVEL_USER);
