// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "textcon.h"

#include <assert.h>
#include <string.h>
#include <zircon/compiler.h>

#include <fbl/algorithm.h>

static inline void invalidate(textcon_t* tc, int x, int y, int w, int h) {
  tc->invalidate(tc->cookie, x, y, w, h);
}
static inline void movecursor(textcon_t* tc, int x, int y) { tc->movecursor(tc->cookie, x, y); }
static inline void push_scrollback_line(textcon_t* tc, int y) {
  tc->push_scrollback_line(tc->cookie, y);
}
static inline void setparam(textcon_t* tc, int param, uint8_t* arg, size_t arglen) {
  tc->setparam(tc->cookie, param, arg, arglen);
}

// Construct a vc_char_t from the given character using the current colors.
static inline vc_char_t make_vc_char(textcon_t* tc, uint8_t ch) {
  return (vc_char_t)(ch | (((vc_char_t)tc->fg & 15) << 8) | (((vc_char_t)tc->bg & 15) << 12));
}

// Note that x coordinates are allowed to be one-past-the-end, as
// described in textcon.h.
static vc_char_t* dataxy(textcon_t* tc, int x, int y) {
  assert(x >= 0);
  // In particular, this assertion is <= to allow the one-past-the-end.
  assert(x <= tc->w);
  assert(y >= 0);
  assert(y < tc->h);
  return tc->data + y * tc->w + x;
}

static vc_char_t* get_start_of_line(textcon_t* tc, int y) {
  assert(y >= 0);
  assert(y <= tc->h);
  return tc->data + y * tc->w;
}

static int clampx(textcon_t* tc, int x) { return x < 0 ? 0 : x >= tc->w ? tc->w - 1 : x; }

static int clampxatedge(textcon_t* tc, int x) { return x < 0 ? 0 : x > tc->w ? tc->w : x; }

static int clampy(textcon_t* tc, int y) { return y < 0 ? 0 : y >= tc->h ? tc->h - 1 : y; }

static void moveto(textcon_t* tc, int x, int y) {
  tc->x = clampx(tc, x);
  tc->y = clampy(tc, y);
}

static inline void moverel(textcon_t* tc, int dx, int dy) { moveto(tc, tc->x + dx, tc->y + dy); }

static void fill(vc_char_t* ptr, vc_char_t val, size_t count) {
  while (count-- > 0) {
    *ptr++ = val;
  }
}

static void erase_region(textcon_t* tc, int x0, int y0, int x1, int y1) {
  if (x0 >= tc->w) {
    return;
  }
  x1 = clampx(tc, x1);
  vc_char_t* ptr = dataxy(tc, x0, y0);
  vc_char_t* end = dataxy(tc, x1, y1) + 1;
  fill(ptr, make_vc_char(tc, ' '), end - ptr);
  invalidate(tc, x0, y0, x1 - x0 + 1, y1 - y0 + 1);
}

static void erase_screen(textcon_t* tc, int arg) {
  switch (arg) {
    case 0:  // erase downward
      erase_region(tc, tc->x, tc->y, tc->w - 1, tc->h - 1);
      break;
    case 1:  // erase upward
      erase_region(tc, 0, 0, tc->x, tc->y);
      break;
    case 2:  // erase all
      erase_region(tc, 0, 0, tc->w - 1, tc->h - 1);
      break;
  }
}

static void erase_line(textcon_t* tc, int arg) {
  switch (arg) {
    case 0:  // erase to EOL
      erase_region(tc, tc->x, tc->y, tc->w - 1, tc->y);
      break;
    case 1:  // erase from BOL
      erase_region(tc, 0, tc->y, tc->x, tc->y);
      break;
    case 2:  // erase line
      erase_region(tc, 0, tc->y, tc->w - 1, tc->y);
      break;
  }
}

static void erase_chars(textcon_t* tc, int arg) {
  if (tc->x >= tc->w) {
    return;
  }
  if (arg < 0) {
    arg = 0;
  }
  int x_erase_end = fbl::min(tc->x + arg, tc->w);

  vc_char_t* dst = dataxy(tc, tc->x, tc->y);
  vc_char_t* src = dataxy(tc, x_erase_end, tc->y);
  vc_char_t* end = dataxy(tc, tc->w, tc->y);

  while (src < end) {
    *dst++ = *src++;
  }
  while (dst < end) {
    *dst++ = make_vc_char(tc, ' ');
  }

  invalidate(tc, tc->x, tc->y, tc->w - tc->x, 1);
}

void tc_copy_lines(textcon_t* tc, int y_dest, int y_src, int line_count) {
  vc_char_t* dest = get_start_of_line(tc, y_dest);
  vc_char_t* src = get_start_of_line(tc, y_src);
  memmove(dest, src, line_count * tc->w * sizeof(vc_char_t));
}

static void clear_lines(textcon_t* tc, int y, int line_count) {
  fill(get_start_of_line(tc, y), make_vc_char(tc, ' '), line_count * tc->w);
  invalidate(tc, 0, y, tc->w, line_count);
}

// Scroll the region between line |y0| (inclusive) and |y1| (exclusive).
// Scroll by |diff| lines, which may be positive (for moving lines up) or
// negative (for moving lines down).
static void scroll_lines(textcon_t* tc, int y0, int y1, int diff) {
  int delta = diff > 0 ? diff : -diff;
  if (delta > y1 - y0)
    delta = y1 - y0;
  int copy_count = y1 - y0 - delta;
  if (diff > 0) {
    // Scroll up.
    for (int i = 0; i < delta; ++i) {
      push_scrollback_line(tc, y0 + i);
    }
    tc->copy_lines(tc->cookie, y0, y0 + delta, copy_count);
    clear_lines(tc, y0 + copy_count, delta);
  } else {
    // Scroll down.
    tc->copy_lines(tc->cookie, y0 + delta, y0, copy_count);
    clear_lines(tc, y0, delta);
  }
}

static void scroll_up(textcon_t* tc) { scroll_lines(tc, tc->scroll_y0, tc->scroll_y1, 1); }

// positive = up, negative = down
static void scroll_at_pos(textcon_t* tc, int dir) {
  if (tc->y < tc->scroll_y0)
    return;
  if (tc->y >= tc->scroll_y1)
    return;

  scroll_lines(tc, tc->y, tc->scroll_y1, dir);
}

void set_scroll(textcon_t* tc, int y0, int y1) {
  if (y0 > y1) {
    return;
  }
  tc->scroll_y0 = (y0 < 0) ? 0 : y0;
  tc->scroll_y1 = (y1 > tc->h) ? tc->h : y1;
}

static void savecursorpos(textcon_t* tc) {
  tc->save_x = tc->x;
  tc->save_y = tc->y;
}

static void restorecursorpos(textcon_t* tc) {
  tc->x = clampxatedge(tc, tc->save_x);
  tc->y = clampy(tc, tc->save_y);
}

static void putc_plain(textcon_t* tc, uint8_t c);
static void putc_escape2(textcon_t* tc, uint8_t c);

static void putc_ignore(textcon_t* tc, uint8_t c) { tc->putc = putc_plain; }

static void putc_param(textcon_t* tc, uint8_t c) {
  switch (c) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      tc->num = tc->num * 10 + (c - '0');
      return;
    case ';':
      if (tc->argn_count < TC_MAX_ARG) {
        tc->argn[tc->argn_count++] = tc->num;
      }
      tc->putc = putc_escape2;
      break;
    default:
      if (tc->argn_count < TC_MAX_ARG) {
        tc->argn[tc->argn_count++] = tc->num;
      }
      tc->putc = putc_escape2;
      putc_escape2(tc, c);
      break;
  }
}

#define ARG0(def) ((tc->argn_count > 0) ? tc->argn[0] : (def))
#define ARG1(def) ((tc->argn_count > 1) ? tc->argn[1] : (def))

static void putc_dec(textcon_t* tc, uint8_t c) {
  switch (c) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      tc->num = tc->num * 10 + (c - '0');
      return;
    case 'h':
      if (tc->num == 25)
        setparam(tc, TC_SHOW_CURSOR, NULL, 0);
      break;
    case 'l':
      if (tc->num == 25)
        setparam(tc, TC_HIDE_CURSOR, NULL, 0);
      break;
    default:
      putc_plain(tc, c);
      break;
  }
  tc->putc = putc_plain;
}

static textcon_param_t osc_to_param(int osc) {
  switch (osc) {
    case 2:
      return TC_SET_TITLE;
    default:
      return TC_INVALID;
  }
}

static void putc_osc2(textcon_t* tc, uint8_t c) {
  switch (c) {
    case 7: {  // end command
      textcon_param_t param = osc_to_param(ARG0(-1));
      if (param != TC_INVALID && tc->argstr_size)
        setparam(tc, param, tc->argstr, tc->argstr_size);
      tc->putc = putc_plain;
      break;
    }
    default:
      if (tc->argstr_size < TC_MAX_ARG_LENGTH)
        tc->argstr[tc->argstr_size++] = c;
      break;
  }
}

static void putc_osc(textcon_t* tc, uint8_t c) {
  switch (c) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      tc->num = tc->num * 10 + (c - '0');
      return;
    case ';':
      if (tc->argn_count < TC_MAX_ARG) {
        tc->argn[tc->argn_count++] = tc->num;
      }
      memset(tc->argstr, 0, TC_MAX_ARG_LENGTH);
      tc->argstr_size = 0;
      tc->putc = putc_osc2;
      break;
    default:
      if (tc->argn_count < TC_MAX_ARG) {
        tc->argn[tc->argn_count++] = tc->num;
      }
      tc->putc = putc_osc2;
      putc_osc2(tc, c);
      break;
  }
}

static void putc_escape2(textcon_t* tc, uint8_t c) {
  int x, y;
  switch (c) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
      tc->num = c - '0';
      tc->putc = putc_param;
      return;
    case ';':  // end parameter
      if (tc->argn_count < TC_MAX_ARG) {
        tc->argn[tc->argn_count++] = 0;
      }
      return;
    case '?':
      tc->num = 0;
      tc->argn_count = 0;
      tc->putc = putc_dec;
      return;
    case 'A':  // (CUU) Cursor Up
      moverel(tc, 0, -ARG0(1));
      break;
    case 'B':  // (CUD) Cursor Down
      moverel(tc, 0, ARG0(1));
      break;
    case 'C':  // (CUF) Cursor Forward
      moverel(tc, ARG0(1), 0);
      break;
    case 'D':  // (CUB) Cursor Backward
      moverel(tc, -ARG0(1), 0);
      break;
    case 'E':
      moveto(tc, 0, tc->y + ARG0(1));
      break;
    case 'F':
      moveto(tc, 0, tc->y - ARG0(1));
      break;
    case 'G':  // move xpos absolute
      x = ARG0(1);
      moveto(tc, x ? (x - 1) : 0, tc->y);
      break;
    case 'H':  // (CUP) Cursor Position
    case 'f':  // (HVP) Horizontal and Vertical Position
      x = ARG1(1);
      y = ARG0(1);
      moveto(tc, x ? (x - 1) : 0, y ? (y - 1) : 0);
      break;
    case 'J':  // (ED) erase in display
      erase_screen(tc, ARG0(0));
      break;
    case 'K':  // (EL) erase in line
      erase_line(tc, ARG0(0));
      break;
    case 'L':  // (IL) insert line(s) at cursor
      scroll_at_pos(tc, -ARG0(1));
      break;
    case 'M':  // (DL) delete line(s) at cursor
      scroll_at_pos(tc, ARG0(1));
      break;
    case 'P':  // (DCH) delete character(s)
      erase_chars(tc, ARG0(1));
      break;
    case 'd':  // move ypos absolute
      y = ARG0(1);
      moveto(tc, tc->x, y ? (y - 1) : 0);
      break;
    case 'm':                     // (SGR) Character Attributes
      if (tc->argn_count == 0) {  // no params == default param
        tc->argn[0] = 0;
        tc->argn_count = 1;
      }
      for (int i = 0; i < tc->argn_count; i++) {
        int n = tc->argn[i];
        if ((n >= 30) && (n <= 37)) {  // set fg
          tc->fg = (uint8_t)(n - 30);
        } else if ((n >= 40) && (n <= 47)) {  // set bg
          tc->bg = (uint8_t)(n - 40);
        } else if ((n == 1) && (tc->fg <= 7)) {  // bold
          tc->fg = (uint8_t)(tc->fg + 8);
        } else if (n == 0) {  // reset
          tc->fg = tc->init_fg;
          tc->bg = tc->init_bg;
        } else if (n == 7) {  // reverse
          uint8_t temp = tc->fg;
          tc->fg = tc->bg;
          tc->bg = temp;
        } else if (n == 39) {  // default fg
          tc->fg = tc->init_fg;
        } else if (n == 49) {  // default bg
          tc->bg = tc->init_bg;
        }
      }
      break;
    case 'r':  // set scroll region
      set_scroll(tc, ARG0(1) - 1, ARG1(tc->h));
      break;
    case 's':  // save cursor position ??
      savecursorpos(tc);
      break;
    case 'u':  // restore cursor position ??
      restorecursorpos(tc);
      break;
    case '@':  // (ICH) Insert Blank Character(s)
    case 'T':  // Initiate Highlight Mouse Tracking (xterm)
    case 'c':  // (DA) Send Device Attributes
    case 'g':  // (TBC) Tab Clear
    case 'h':  // (SM) Set Mode  (4=Insert,20=AutoNewline)
    case 'l':  // (RM) Reset Mode (4=Replace,20=NormalLinefeed)
    case 'n':  // (DSR) Device Status Report
    case 'x':  // Request Terminal Parameters
    default:
      break;
  }
  movecursor(tc, tc->x, tc->y);
  tc->putc = putc_plain;
}

static void putc_escape(textcon_t* tc, uint8_t c) {
  switch (c) {
    case 27:  // escape
      return;
    case '(':
    case ')':
    case '*':
    case '+':
      // select various character sets
      tc->putc = putc_ignore;
      return;
    case '[':
      tc->num = 0;
      tc->argn_count = 0;
      tc->putc = putc_escape2;
      return;
    case ']':
      tc->num = 0;
      tc->argn_count = 0;
      tc->putc = putc_osc;
      return;
    case '7':  // (DECSC) Save Cursor
      savecursorpos(tc);
      // save attribute
      break;
    case '8':  // (DECRC) Restore Cursor
      restorecursorpos(tc);
      movecursor(tc, tc->x, tc->y);
      break;
    case 'E':  // (NEL) Next Line
      tc->x = 0;
      __FALLTHROUGH;
    case 'D':  // (IND) Index
      tc->y++;
      if (tc->y >= tc->scroll_y1) {
        tc->y--;
        scroll_up(tc);
      }
      movecursor(tc, tc->x, tc->y);
      break;
    case 'M':  // (RI) Reverse Index)
      tc->y--;
      if (tc->y < tc->scroll_y0) {
        tc->y++;
        scroll_at_pos(tc, -1);
      }
      movecursor(tc, tc->x, tc->y);
      break;
  }
  tc->putc = putc_plain;
}

static void putc_cr(textcon_t* tc) { tc->x = 0; }

static void putc_lf(textcon_t* tc) {
  tc->y++;
  if (tc->y >= tc->scroll_y1) {
    tc->y--;
    scroll_up(tc);
  }
}

static void putc_plain(textcon_t* tc, uint8_t c) {
  switch (c) {
    case 7:  // bell
      break;
    case 8:  // backspace / ^H
      if (tc->x > 0)
        tc->x--;
      break;
    case 9:  // tab / ^I
      moveto(tc, (tc->x + 8) & (~7), tc->y);
      break;
    case 10:        // newline
      putc_cr(tc);  // should we imply this?
      putc_lf(tc);
      break;
    case 12:
      erase_screen(tc, 2);
      break;
    case 13:  // carriage return
      putc_cr(tc);
      break;
    case 27:  // escape
      tc->putc = putc_escape;
      return;
    default:
      if ((c < ' ') || (c > 127)) {
        return;
      }
      if (tc->x >= tc->w) {
        // Apply deferred line wrap upon printing first character beyond
        // end of current line.
        putc_cr(tc);
        putc_lf(tc);
      }
      dataxy(tc, tc->x, tc->y)[0] = make_vc_char(tc, c);
      invalidate(tc, tc->x, tc->y, 1, 1);
      tc->x++;
      break;
  }
  movecursor(tc, tc->x, tc->y);
}

void tc_init(textcon_t* tc, int w, int h, vc_char_t* data, uint8_t fg, uint8_t bg, int cursor_x,
             int cursor_y) {
  tc->w = w;
  tc->h = h;
  tc->x = cursor_x;
  tc->y = cursor_y;
  tc->data = data;
  tc->scroll_y0 = 0;
  tc->scroll_y1 = h;
  tc->save_x = 0;
  tc->save_y = 0;
  tc->fg = fg;
  tc->bg = bg;
  tc->init_fg = fg;
  tc->init_bg = bg;
  tc->putc = putc_plain;
}

void tc_seth(textcon_t* tc, int h) {
  // tc->data must be big enough for the new height
  int old_h = h;
  tc->h = h;

  // Move contents.
  int y = 0;
  if (old_h > h) {
    vc_char_t* dst = dataxy(tc, 0, tc->scroll_y0);
    vc_char_t* src = dataxy(tc, 0, tc->scroll_y0 + old_h - h);
    vc_char_t* end = dataxy(tc, 0, tc->scroll_y1);
    do {
      push_scrollback_line(tc, y);
    } while (++y < old_h - h);
    memmove(dst, src, (end - dst) * sizeof(vc_char_t));
    tc->y -= old_h - h;
  } else if (old_h < h) {
    do {
      fill(dataxy(tc, 0, tc->scroll_y1 + y), make_vc_char(tc, ' '), tc->w);
    } while (++y < h - old_h);
  }
  tc->y = clampy(tc, tc->y);

  // Try to fix up the scroll region.
  if (tc->scroll_y0 >= h) {
    tc->scroll_y0 = 0;
  }
  if (tc->scroll_y1 == old_h) {
    tc->scroll_y1 = h;
  } else {
    tc->scroll_y1 = tc->scroll_y1 >= h ? h : tc->scroll_y1;
  }

  invalidate(tc, 0, 0, tc->w, tc->h);
  movecursor(tc, tc->x, tc->y);
}
