// 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/boot-options/boot-options.h>
#include <lib/console.h>
#include <lib/debuglog.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>

#include <ktl/enforce.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 int cmd_boot_test_success(int argc, const cmd_args* argv, uint32_t flags);
static int cmd_graceful_shutdown(int argc, const cmd_args* argv, uint32_t flags);
static int cmd_and(int argc, const cmd_args* argv, uint32_t flags);
static int cmd_repeat(int argc, const cmd_args* argv, uint32_t flags);

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("and", "execute command if last command succeeded", &cmd_and,
                      CMD_AVAIL_ALWAYS)
STATIC_COMMAND_MASKED("repeat", "execute command in a loop for N loops or until error", &cmd_repeat,
                      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_MASKED("boot-test-success", "report boot-test success", &cmd_boot_test_success,
                      CMD_AVAIL_ALWAYS)
STATIC_COMMAND_MASKED("graceful-shutdown", "shut the system down gracefully",
                      &cmd_graceful_shutdown, CMD_AVAIL_ALWAYS)
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);
      lastresult = -1;
      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 (char c = lineread->string[lineread->pos]; c == '\n' || c == ';') {
      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];

  // Panic may have been triggered via an interrupt/exception path, where blocking would normally
  // disallowed. As some panic shell commands need to take mutexes and perform other operations that
  // would otherwise be invalid if blocking is disallowed we re-allow it.
  arch_set_blocking_disallowed(false);

  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 int cmd_boot_test_success(int argc, const cmd_args* argv, uint32_t flags) {
  printf("*** Last script command result: %d ***\n", lastresult);
  if (lastresult == 0) {
    printf("%s\n", BOOT_TEST_SUCCESS_STRING);
  }
  return lastresult;
}

static int cmd_graceful_shutdown(int argc, const cmd_args* argv, uint32_t flags) {
  printf("*** Performing graceful shutdown from kernel shell... ***\n");
  const zx_time_t dlog_deadline = current_time() + ZX_SEC(10);
  dlog_shutdown(dlog_deadline);
  // Does not return.
  platform_halt(HALT_ACTION_SHUTDOWN, ZirconCrashReason::NoCrash);
}

static int cmd_and(int argc, const cmd_args* argv, uint32_t flags) {
  if (argc < 2) {
    printf("Usage: and COMMAND...\n");
    return -1;
  }

  if (lastresult != 0) {
    return lastresult;
  }

  const cmd* cmd = match_command(argv[1].str, CMD_AVAIL_NORMAL);
  if (!cmd) {
    printf("command \"%s\" not found\n", argv[1].str);
    return -1;
  }

  return cmd->cmd_callback(argc - 1, argv + 1, flags);
}

static int cmd_repeat(int argc, const cmd_args* argv, uint32_t flags) {
  if (argc < 3) {
    printf("Usage: repeat <iterations | -1> COMMAND...\n");
    return -1;
  }

  const cmd* cmd = match_command(argv[2].str, CMD_AVAIL_NORMAL);
  if (!cmd) {
    printf("command \"%s\" not found\n", argv[2].str);
    return -1;
  }

  // negative arguments will cause it to effectively loop forever
  size_t term = argv[1].i >= 0 ? argv[1].u : SIZE_MAX;
  for (size_t loop = 0; loop < term; loop++) {
    if (term == SIZE_MAX) {
      printf("repeat (%zu): %s", loop + 1, argv[2].str);
    } else {
      printf("repeat (%zu/%zu): %s", loop + 1, term, argv[2].str);
    }
    for (int a = 3; a < argc; a++) {
      printf(" %s", argv[a].str);
    }
    printf("\n");
    int err = cmd->cmd_callback(argc - 2, argv + 2, flags);
    if (err != 0) {
      printf("stopping repeat due to nonzero status %d\n", err);
      return err;
    }
  }

  return ZX_OK;
}

static constexpr TimerSlack kSlack{ZX_MSEC(10), TIMER_SLACK_CENTER};

void RecurringCallback::CallbackWrapper(Timer* t, zx_time_t now, void* arg) {
  auto cb = static_cast<RecurringCallback*>(arg);
  cb->func_();

  {
    Guard<SpinLock, IrqSave> guard{&cb->lock_};

    if (cb->started_) {
      const Deadline deadline(zx_time_add_duration(now, ZX_SEC(1)), kSlack);
      t->Set(deadline, CallbackWrapper, arg);
    }
  }

  // reschedule to give the debuglog a chance to run
  Thread::Current::preemption_state().PreemptSetPending();
}

void RecurringCallback::Toggle() {
  Guard<SpinLock, IrqSave> guard{&lock_};

  if (!started_) {
    const Deadline deadline = Deadline::after(ZX_SEC(1), kSlack);
    // start the timer
    timer_.Set(deadline, CallbackWrapper, static_cast<void*>(this));
    started_ = true;
  } else {
    timer_.Cancel();
    started_ = false;
  }
}

static void kernel_shell_init(uint level) {
  if (!gBootOptions->shell_script.empty()) {
    SmallString script = gBootOptions->shell_script;
    for (char* p = strchr(script.data(), '+'); p; p = strchr(p + 1, '+')) {
      *p = ' ';
    }
    console_run_script(script.data());
  }
  if (gBootOptions->shell) {
    console_start();
  }
}

LK_INIT_HOOK(kernel_shell, kernel_shell_init, LK_INIT_LEVEL_USER)
