// 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 <assert.h>
#include <ctype.h>
#include <debug.h>
#include <lib/cmdline.h>
#include <lib/console.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <trace.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <kernel/mutex.h>
#include <kernel/thread.h>
#include <ktl/algorithm.h>
#include <ktl/unique_ptr.h>
#include <lk/init.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 */
namespace {
DECLARE_SINGLETON_MUTEX(CommandLock);
}  // namespace
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)
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
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 = strtoul(argv[i].str, nullptr, 0);
    argv[i].u = u;
    argv[i].p = (void*)u;
    argv[i].i = strtol(argv[i].str, nullptr, 0);

    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)
      CommandLock::Get()->lock().Acquire();

    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)
      CommandLock::Get()->lock().Release();
  }

  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;

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

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

static int cmd_help(int argc, const cmd_args* argv, uint32_t flags) {
  auto print_cmds = [&flags](auto begin, auto end) {
    // Filter out commands based on if we're called at normal or panic time.
    const uint8_t availability_mask = (flags & CMD_FLAG_PANIC) ? CMD_AVAIL_PANIC : CMD_AVAIL_NORMAL;

    printf("command list:\n");
    for (auto it = begin; it != end; ++it) {
      const cmd& curr_cmd = *it;
      if ((availability_mask & curr_cmd.availability_mask) == 0) {
        continue;
      }
      if (curr_cmd.help_str)
        printf("\t%-16s: %s\n", curr_cmd.cmd_str, curr_cmd.help_str);
    }
  };

  // If we're not panicking (and are free to allocate memory), sort the
  // commands alphabetically before printing.
  if (flags & CMD_FLAG_PANIC) {
    print_cmds(__start_commands, __stop_commands);
  } else {
    const size_t num_cmds = __stop_commands - __start_commands;
    fbl::AllocChecker ac;
    auto cmds = ktl::make_unique<cmd[]>(&ac, num_cmds);
    if (!ac.check()) {
      return ZX_ERR_NO_MEMORY;
    }
    memcpy(cmds.get(), __start_commands, num_cmds * sizeof(cmd));
    ktl::stable_sort(cmds.get(), cmds.get() + num_cmds, [](const cmd& cmd1, const cmd& cmd2) {
      return strcmp(cmd1.cmd_str, cmd2.cmd_str) < 0;
    });
    print_cmds(cmds.get(), cmds.get() + num_cmds);
  }

  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) < 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);
  }
}

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

static void kernel_shell_init(uint level) {
  if (gCmdline.GetBool(kernel_option::kShell, false)) {
    console_start();
  }
}

LK_INIT_HOOK(kernel_shell, kernel_shell_init, LK_INIT_LEVEL_USER)
