/****************************************************************************
 * interpreters/micropython/py_readline.c
 *
 * This file originated from the Micro Python project, http://micropython.org/
 * It has been hacked around to fit into Nuttx
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2013, 2014 Damien P. George
 * Further edits (c) 2015 Dave Marples
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 ****************************************************************************/

/****************************************************************************
 * Included Files
 ****************************************************************************/

#include <stdio.h>
#include <stdint.h>
#include <string.h>

#include "py/mpconfig.h"
#include "py/misc.h"
#include "py_readline.h"

#if 0                                  /* print debugging info */
#  define DEBUG_PRINT (1)
#  define DEBUG_printf printf
#else                                  /* don't print debugging info */
#  define DEBUG_printf(...) (void)0
#endif

#define READLINE_HIST_SIZE (8)

#define CURSOR_BACK ('\b')
#define KEY_TAB     ('\t')

/****************************************************************************
 * Private Types
 ****************************************************************************/

enum
{
  ESEQ_NONE,
  ESEQ_ESC,
  ESEQ_ESC_BRACKET,
  ESEQ_ESC_BRACKET_DIGIT,
  ESEQ_ESC_O
};

/****************************************************************************
 * Private Data
 ****************************************************************************/

static const char *readline_hist[READLINE_HIST_SIZE];

/****************************************************************************
 * Private Functions
 ****************************************************************************/

STATIC char *str_dup_maybe(const char *str)
{
  uint32_t len = strlen(str);
  char *s2 = m_new_maybe(char, len + 1);

  if (s2 == NULL)
    {
      return NULL;
    }

  memcpy(s2, str, len + 1);
  return s2;
}

/****************************************************************************
 * Public Functions
 ****************************************************************************/

void readline_init0(void)
{
  memset(readline_hist, 0, READLINE_HIST_SIZE * sizeof(const char *));
}

int py_readline(vstr_t * line, const char *prompt)
{
  fprintf(stdout, prompt);
  fflush(stdout);
  int orig_line_len = line->len;
  int escape_seq = ESEQ_NONE;
  char escape_seq_buf[1] = { 0 };
  int hist_cur = -1;
  int cursor_pos = orig_line_len;

  for (;;)
    {
      int c = getc(stdin);
      int last_line_len = line->len;
      int redraw_step_back = 0;
      bool redraw_from_cursor = false;
      int redraw_step_forward = 0;
      if (escape_seq == ESEQ_NONE)
        {
          if (CHAR_CTRL_A <= c && c <= CHAR_CTRL_D &&
              vstr_len(line) == orig_line_len)
            {
              /* control character with empty line */

              return c;
            }
          else if (c == CHAR_CTRL_A)
            {
              /* CTRL-A with non-empty line is go-to-start-of-line */

              goto home_key;
            }
          else if (c == CHAR_CTRL_C)
            {
              /* CTRL-C with non-empty line is cancel */

              return c;
            }
          else if (c == CHAR_CTRL_E)
            {
              /* CTRL-E is go-to-end-of-line */

              goto end_key;
            }
          else if (c == '\r')
            {
              /* newline */

              fputs("\r\n", stdout);
              if (line->len > orig_line_len &&
                  (readline_hist[0] == NULL ||
                   strcmp(readline_hist[0], line->buf + orig_line_len) != 0))
                {
                  /* a line which is not empty and different from the last one
                   * so update the history
                   */

                  char *most_recent_hist =
                    str_dup_maybe(line->buf + orig_line_len);
                  if (most_recent_hist != NULL)
                    {
                      for (int i = READLINE_HIST_SIZE - 1; i > 0; i--)
                        {
                          readline_hist[i] = readline_hist[i - 1];
                        }

                      readline_hist[0] = most_recent_hist;
                    }
                }

              return 0;
            }
          else if (c == 27)
            {
              /* escape sequence */

              escape_seq = ESEQ_ESC;
            }
          else if (c == 8 || c == 127)
            {
              /* backspace/delete */

              if (cursor_pos > orig_line_len)
                {
                  vstr_cut_out_bytes(line, cursor_pos - 1, 1);

                  /* set redraw parameters */

                  redraw_step_back = 1;
                  redraw_from_cursor = true;
                }
            }
          else if ((KEY_TAB == c) || (32 <= c && c <= 126))
            {
              /* printable character */

              vstr_ins_char(line, cursor_pos, c);

              /* set redraw parameters */

              redraw_from_cursor = true;
              redraw_step_forward = 1;
            }
        }
      else if (escape_seq == ESEQ_ESC)
        {
          switch (c)
            {
            case '[':
              escape_seq = ESEQ_ESC_BRACKET;
              break;

            case 'O':
              escape_seq = ESEQ_ESC_O;
              break;

            default:
              DEBUG_printf("(ESC %d)", c);
              escape_seq = ESEQ_NONE;
            }
        }
      else if (escape_seq == ESEQ_ESC_BRACKET)
        {
          if ('0' <= c && c <= '9')
            {
              escape_seq = ESEQ_ESC_BRACKET_DIGIT;
              escape_seq_buf[0] = c;
            }
          else
            {
              escape_seq = ESEQ_NONE;
              if (c == 'A')
                {
                  /* up arrow */

                  if (hist_cur + 1 < READLINE_HIST_SIZE &&
                      readline_hist[hist_cur + 1] != NULL)
                    {
                      /* increase hist num */

                      hist_cur += 1;

                      /* set line to history */

                      line->len = orig_line_len;
                      vstr_add_str(line, readline_hist[hist_cur]);

                      /* set redraw parameters */

                      redraw_step_back = cursor_pos - orig_line_len;
                      redraw_from_cursor = true;
                      redraw_step_forward = line->len - orig_line_len;
                    }
                }
              else if (c == 'B')
                {
                  /* down arrow */

                  if (hist_cur >= 0)
                    {
                      /* decrease hist num */

                      hist_cur -= 1;

                      /* set line to history */

                      vstr_cut_tail_bytes(line, line->len - orig_line_len);
                      if (hist_cur >= 0)
                        {
                          vstr_add_str(line, readline_hist[hist_cur]);
                        }

                      /* set redraw parameters */

                      redraw_step_back = cursor_pos - orig_line_len;
                      redraw_from_cursor = true;
                      redraw_step_forward = line->len - orig_line_len;
                    }
                }
              else if (c == 'C')
                {
                  /* right arrow */

                  if (cursor_pos < line->len)
                    {
                      redraw_step_forward = 1;
                    }
                }
              else if (c == 'D')
                {
                  /* left arrow */

                  if (cursor_pos > orig_line_len)
                    {
                      redraw_step_back = 1;
                    }
                }
              else if (c == 'H')
                {
                  /* home */

                  goto home_key;
                }
              else if (c == 'F')
                {
                  /* end */

                  goto end_key;
                }
              else
                {
                  DEBUG_printf("(ESC [ %d)", c);
                }
            }
        }
      else if (escape_seq == ESEQ_ESC_BRACKET_DIGIT)
        {
          if (c == '~')
            {
              if (escape_seq_buf[0] == '1' || escape_seq_buf[0] == '7')
                {
                home_key:
                  redraw_step_back = cursor_pos - orig_line_len;
                }
              else if (escape_seq_buf[0] == '4' || escape_seq_buf[0] == '8')
                {
                end_key:
                  redraw_step_forward = line->len - cursor_pos;
                }
              else
                {
                  DEBUG_printf("(ESC [ %c %d)", escape_seq_buf[0], c);
                }
            }
          else
            {
              DEBUG_printf("(ESC [ %c %d)", escape_seq_buf[0], c);
            }

          escape_seq = ESEQ_NONE;
        }
      else if (escape_seq == ESEQ_ESC_O)
        {
          switch (c)
            {
            case 'H':
              goto home_key;

            case 'F':
              goto end_key;

            default:
              DEBUG_printf("(ESC O %d)", c);
              escape_seq = ESEQ_NONE;
            }
        }
      else
        {
          escape_seq = ESEQ_NONE;
        }

      /* redraw command prompt, efficiently
       * TODO we can probably use some more sophisticated VT100 commands here
       */

      if (redraw_step_back > 0)
        {
          for (int i = 0; i < redraw_step_back; i++)
            {
              fputc(CURSOR_BACK, stdout);
            }

          cursor_pos -= redraw_step_back;
        }
      if (redraw_from_cursor)
        {
          if (line->len < last_line_len)
            {
              /* erase old chars */

              for (int i = cursor_pos; i < last_line_len; i++)
                {
                  fputc(' ', stdout);
                }

              /* step back */

              for (int i = cursor_pos; i < last_line_len; i++)
                {
                  fputc(CURSOR_BACK, stdout);
                }
            }

          /* draw new chars */

          int charCount = 0;
          do
            {
              fputc(*(line->buf + cursor_pos + charCount), stdout);
            }
          while (charCount++ < (line->len - cursor_pos));

          /* move cursor forward if needed (already moved forward by length of
           * line, so move it back)
           */

          for (int i = cursor_pos + redraw_step_forward; i < line->len; i++)
            {
              fputc(CURSOR_BACK, stdout);
            }

          cursor_pos += redraw_step_forward;
        }
      else if (redraw_step_forward > 0)
        {
          /* draw over old chars to move cursor forwards */

          int charCount = 0;
          do
            {
              fputc(*(line->buf + cursor_pos + charCount), stdout);
            }

          while (charCount++ < redraw_step_forward);
          cursor_pos += redraw_step_forward;
        }

      fflush(stdout);
    }
}
