// 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 <assert.h>
#include <fcntl.h>
#include <lib/gfx-font-data/gfx-font-data.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>

#include <fbl/auto_lock.h>

#include "vc.h"

// Default height/width (in px) of console before any displays are
// attached, since we need somewhere to put any data that is received.
#define DEFAULT_WIDTH 1024
#define DEFAULT_HEIGHT 768
#define SCROLLBACK_ROWS 1024  // TODO make configurable

#define ABS(val) (((val) >= 0) ? (val) : -(val))

const gfx_font* g_font = &gfx_font_9x16;
const keychar_t* g_keymap = qwerty_map;

static zx_status_t vc_setup(vc_t* vc, const color_scheme_t* color_scheme) {
  // calculate how many rows/columns we have
  vc->rows = DEFAULT_HEIGHT / vc->charh;
  vc->columns = DEFAULT_WIDTH / vc->charw;
  vc->scrollback_rows_max = SCROLLBACK_ROWS;
  vc->scrollback_rows_count = 0;
  vc->scrollback_offset = 0;

  // allocate the text buffer
  vc->text_buf =
      reinterpret_cast<vc_char_t*>(calloc(1, vc->rows * vc->columns * sizeof(vc_char_t)));
  if (!vc->text_buf)
    return ZX_ERR_NO_MEMORY;

  // allocate the scrollback buffer
  vc->scrollback_buf = reinterpret_cast<vc_char_t*>(
      calloc(1, vc->scrollback_rows_max * vc->columns * sizeof(vc_char_t)));
  if (!vc->scrollback_buf) {
    free(vc->text_buf);
    return ZX_ERR_NO_MEMORY;
  }

  // set up the default palette
  memcpy(&vc->palette, default_palette, sizeof(default_palette));

  vc->front_color = color_scheme->front;
  vc->back_color = color_scheme->back;

  return ZX_OK;
}

bool vc_graphics_enabled(vc_t* vc) { return vc->graphics && vc->graphics->vc_gfx; }

static void vc_invalidate(void* cookie, int x0, int y0, int w, int h) {
  vc_t* vc = reinterpret_cast<vc_t*>(cookie);

  if (!g_vc_owns_display || !vc->active || !vc_graphics_enabled(vc)) {
    return;
  }

  assert(h >= 0);
  int y1 = y0 + h;
  assert(y0 <= static_cast<int>(vc->rows));
  assert(y1 <= static_cast<int>(vc->rows));

  // Clip the y range so that we don't unnecessarily draw characters
  // outside the visible range, and so that we don't draw characters into
  // the bottom margin.
  int visible_y0 = vc->viewport_y;
  int visible_y1 = vc->viewport_y + vc_rows(vc);
  y0 = MAX(y0, visible_y0);
  y1 = MIN(y1, visible_y1);

  for (int y = y0; y < y1; y++) {
    if (y < 0) {
      // Scrollback row.
      vc_char_t* row = vc_get_scrollback_line_ptr(vc, y + vc->scrollback_rows_count);
      for (int x = x0; x < x0 + w; x++) {
        vc_gfx_draw_char(vc->graphics, vc, row[x], x, y - vc->viewport_y,
                         /* invert= */ false);
      }
    } else {
      // Row in the main console region (non-scrollback).
      vc_char_t* row = &vc->text_buf[y * vc->columns];
      for (int x = x0; x < x0 + w; x++) {
        // Check whether we should display the cursor at this
        // position.  Note that it's possible that the cursor is
        // outside the display area (vc->cursor_x ==
        // vc->columns).  In that case, we won't display the
        // cursor, even if there's a margin.  This matches
        // gnome-terminal.
        bool invert = (!vc->hide_cursor && static_cast<unsigned>(x) == vc->cursor_x &&
                       static_cast<unsigned>(y) == vc->cursor_y);
        vc_gfx_draw_char(vc->graphics, vc, row[x], x, y - vc->viewport_y, invert);
      }
    }
  }
}

// implement tc callbacks:

static inline void vc_invalidate_lines(vc_t* vc, int y, int h) {
  if (y < vc->invy0) {
    vc->invy0 = y;
  }
  y += h;
  if (y > vc->invy1) {
    vc->invy1 = y;
  }
}

static void vc_tc_invalidate(void* cookie, int x0, int y0, int w, int h) {
  vc_t* vc = reinterpret_cast<vc_t*>(cookie);
  vc_invalidate(cookie, x0, y0, w, h);
  vc_invalidate_lines(vc, y0, h);
}

static void vc_tc_movecursor(void* cookie, int x, int y) {
  vc_t* vc = reinterpret_cast<vc_t*>(cookie);
  unsigned old_x = vc->cursor_x;
  unsigned old_y = vc->cursor_y;
  vc->cursor_x = x;
  vc->cursor_y = y;
  if (g_vc_owns_display && vc->active && !vc->hide_cursor) {
    // Clear the cursor from its old position.
    vc_invalidate(cookie, old_x, old_y, 1, 1);
    vc_invalidate_lines(vc, old_y, 1);

    // Display the cursor in its new position.
    vc_invalidate(cookie, vc->cursor_x, vc->cursor_y, 1, 1);
    vc_invalidate_lines(vc, vc->cursor_y, 1);
  }
}

static void vc_tc_scrollback_buffer_push(vc_t* vc, vc_char_t* src) {
  unsigned dest_row;
  assert(vc->scrollback_rows_count <= vc->scrollback_rows_max);
  if (vc->scrollback_rows_count < vc->scrollback_rows_max) {
    // Add a row without dropping any existing rows.
    assert(vc->scrollback_offset == 0);
    dest_row = vc->scrollback_rows_count++;
  } else {
    // Add a row and drop an existing row.
    assert(vc->scrollback_offset < vc->scrollback_rows_max);
    dest_row = vc->scrollback_offset++;
    if (vc->scrollback_offset == vc->scrollback_rows_max)
      vc->scrollback_offset = 0;
  }
  vc_char_t* dst = &vc->scrollback_buf[dest_row * vc->columns];
  memcpy(dst, src, vc->columns * sizeof(vc_char_t));
}

static void vc_tc_push_scrollback_line(void* cookie, int y) {
  vc_t* vc = reinterpret_cast<vc_t*>(cookie);
  vc_char_t* src = &vc->text_buf[y * vc->columns];
  vc_tc_scrollback_buffer_push(vc, src);

  // If we're displaying only the main console region (and no
  // scrollback), then keep displaying that (i.e. don't modify
  // viewport_y).
  if (vc->viewport_y < 0) {
    // We are displaying some of the scrollback buffer.
    if (vc->viewport_y > -static_cast<int>(vc->scrollback_rows_max)) {
      // Scroll the viewport to continue displaying the same point in
      // the scrollback buffer.
      --vc->viewport_y;
    } else {
      // We were displaying the line at the top of the scrollback
      // buffer, but we dropped that line from the buffer.  We could
      // leave the display as it was (which is what gnome-terminal
      // does) and not scroll the display.  However, that causes
      // problems.  If the user later scrolls down, we won't
      // necessarily be able to display the lines below -- we might
      // have dropped those too.  So, instead, let's scroll the
      // display and remove the scrollback line that was lost.
      //
      // For simplicity, fall back to redrawing everything.
      vc_invalidate(vc, 0, -vc->scrollback_rows_max, vc->columns, vc_rows(vc));
      vc_render(vc);
    }
  }
}

static void vc_set_cursor_hidden(vc_t* vc, bool hide) {
  if (vc->hide_cursor == hide)
    return;
  vc->hide_cursor = hide;
  if (g_vc_owns_display && vc->active) {
    vc_invalidate(vc, vc->cursor_x, vc->cursor_y, 1, 1);
    vc_invalidate_lines(vc, vc->cursor_y, 1);
  }
}

static void vc_tc_copy_lines(void* cookie, int y_dest, int y_src, int line_count) {
  vc_t* vc = reinterpret_cast<vc_t*>(cookie);

  if (vc->viewport_y < 0) {
    tc_copy_lines(&vc->textcon, y_dest, y_src, line_count);

    // The viewport is scrolled.  For simplicity, fall back to
    // redrawing all of the non-scrollback lines in this case.
    int rows = vc_rows(vc);
    vc_invalidate(vc, 0, 0, vc->columns, rows);
    vc_invalidate_lines(vc, 0, rows);
    return;
  }

  // Remove the cursor from the display before copying the lines on
  // screen, otherwise we might be copying a rendering of the cursor to a
  // position where the cursor isn't.  This must be done before the
  // tc_copy_lines() call, otherwise we might render the wrong character.
  bool old_hide_cursor = vc->hide_cursor;
  if (g_vc_owns_display && vc->active) {
    vc_set_cursor_hidden(vc, true);
  }

  // The next two calls can be done in any order.
  tc_copy_lines(&vc->textcon, y_dest, y_src, line_count);

  if (g_vc_owns_display && vc->active && vc_graphics_enabled(vc)) {
    gfx_copyrect(vc->graphics->vc_gfx, 0, y_src * vc->charh, vc->graphics->vc_gfx->width,
                 line_count * vc->charh, 0, y_dest * vc->charh);

    // Restore the cursor.
    vc_set_cursor_hidden(vc, old_hide_cursor);

    vc_status_update();
    vc_gfx_invalidate_status(vc->graphics);
    vc_invalidate_lines(vc, 0, vc_rows(vc));
  }
}

static void vc_tc_setparam(void* cookie, int param, uint8_t* arg, size_t arglen) {
  vc_t* vc = reinterpret_cast<vc_t*>(cookie);
  switch (param) {
    case TC_SET_TITLE:
      strncpy(vc->title, (char*)arg, sizeof(vc->title));
      vc->title[sizeof(vc->title) - 1] = '\0';
      vc_status_update();
      if (g_vc_owns_display && vc_graphics_enabled(vc)) {
        vc_gfx_invalidate_status(vc->graphics);
      }
      break;
    case TC_SHOW_CURSOR:
      vc_set_cursor_hidden(vc, false);
      break;
    case TC_HIDE_CURSOR:
      vc_set_cursor_hidden(vc, true);
      break;
    default:;  // nothing
  }
}

static void vc_clear_gfx(vc_t* vc) {
  // Fill display with background color
  if (g_vc_owns_display && vc->active && vc_graphics_enabled(vc)) {
    gfx_fillrect(vc->graphics->vc_gfx, 0, 0, vc->graphics->vc_gfx->width,
                 vc->graphics->vc_gfx->height, palette_to_color(vc, vc->back_color));
  }
}

static void vc_reset(vc_t* vc) {
  // reset the cursor
  vc->cursor_x = 0;
  vc->cursor_y = 0;
  // reset the viewport position
  vc->viewport_y = 0;

  tc_init(&vc->textcon, vc->columns, vc_rows(vc), vc->text_buf, vc->front_color, vc->back_color,
          vc->cursor_x, vc->cursor_y);
  vc->textcon.cookie = vc;
  vc->textcon.invalidate = vc_tc_invalidate;
  vc->textcon.movecursor = vc_tc_movecursor;
  vc->textcon.push_scrollback_line = vc_tc_push_scrollback_line;
  vc->textcon.copy_lines = vc_tc_copy_lines;
  vc->textcon.setparam = vc_tc_setparam;

  // fill textbuffer with blank characters
  size_t count = vc->rows * vc->columns;
  vc_char_t* ptr = vc->text_buf;
  while (count--) {
    *ptr++ = vc_char_make(' ', vc->front_color, vc->back_color);
  }

  vc_clear_gfx(vc);
  if (vc_graphics_enabled(vc)) {
    vc_gfx_invalidate_all(vc->graphics, vc);
  }
}

void vc_status_clear() {
  if (g_vc_owns_display && g_active_vc && vc_graphics_enabled(g_active_vc)) {
    gfx_fillrect(g_active_vc->graphics->vc_status_bar_gfx, 0, 0,
                 g_active_vc->graphics->vc_status_bar_gfx->width,
                 g_active_vc->graphics->vc_status_bar_gfx->height,
                 default_palette[STATUS_COLOR_BG]);
  }
}

void vc_status_commit() {
  if (g_vc_owns_display && g_active_vc && vc_graphics_enabled(g_active_vc)) {
    vc_gfx_invalidate_status(g_active_vc->graphics);
  }
}

void vc_status_write(int x, unsigned color, const char* text) {
  char c;
  unsigned fg = default_palette[color];
  unsigned bg = default_palette[STATUS_COLOR_BG];
  vc_t* vc = g_active_vc;
  if (!g_active_vc) {
    return;
  }

  if (g_vc_owns_display && vc_graphics_enabled(vc)) {
    x *= vc->graphics->vc_font->width;
    while ((c = *text++) != 0) {
      gfx_putchar(vc->graphics->vc_status_bar_gfx, vc->graphics->vc_font, c, x, 0, fg, bg);
      x += vc->graphics->vc_font->width;
    }
  }
}

void vc_render(vc_t* vc) {
  if (g_vc_owns_display && vc->active && vc_graphics_enabled(vc)) {
    vc_status_update();
    vc_gfx_invalidate_all(vc->graphics, vc);
  }
}

void vc_full_repaint(vc_t* vc) {
  if (g_vc_owns_display && vc_graphics_enabled(vc)) {
    vc_clear_gfx(vc);
    int scrollback_lines = vc_get_scrollback_lines(vc);
    vc_invalidate(vc, 0, -scrollback_lines, vc->columns, scrollback_lines + vc->rows);
  }
}

int vc_get_scrollback_lines(vc_t* vc) { return vc->scrollback_rows_count; }

vc_char_t* vc_get_scrollback_line_ptr(vc_t* vc, unsigned row) {
  assert(row < vc->scrollback_rows_count);
  row += vc->scrollback_offset;
  if (row >= vc->scrollback_rows_max)
    row -= vc->scrollback_rows_max;
  return &vc->scrollback_buf[row * vc->columns];
}

static void vc_scroll_viewport_abs(vc_t* vc, int vpy) {
  vpy = MIN(vpy, 0);
  vpy = MAX(vpy, -vc_get_scrollback_lines(vc));
  int diff = vpy - vc->viewport_y;
  if (diff == 0)
    return;
  int diff_abs = ABS(diff);
  vc->viewport_y = vpy;
  int rows = vc_rows(vc);
  if (!g_vc_owns_display || !vc->active || !vc_graphics_enabled(vc)) {
    return;
  }
  if (diff_abs >= rows) {
    // We are scrolling the viewport by a large delta.  Invalidate all
    // of the visible area of the console.
    vc_invalidate(vc, 0, vpy, vc->columns, rows);
  } else {
    if (diff > 0) {
      gfx_copyrect(vc->graphics->vc_gfx, 0, diff_abs * vc->charh, vc->graphics->vc_gfx->width,
                   (rows - diff_abs) * vc->charh, 0, 0);
      vc_invalidate(vc, 0, vpy + rows - diff_abs, vc->columns, diff_abs);
    } else {
      gfx_copyrect(vc->graphics->vc_gfx, 0, 0, vc->graphics->vc_gfx->width,
                   (rows - diff_abs) * vc->charh, 0, diff_abs * vc->charh);
      vc_invalidate(vc, 0, vpy, vc->columns, diff_abs);
    }
  }
  vc_render(vc);
}

void vc_scroll_viewport(vc_t* vc, int dir) { vc_scroll_viewport_abs(vc, vc->viewport_y + dir); }

void vc_scroll_viewport_top(vc_t* vc) { vc_scroll_viewport_abs(vc, INT_MIN); }

void vc_scroll_viewport_bottom(vc_t* vc) { vc_scroll_viewport_abs(vc, 0); }

void vc_set_fullscreen(vc_t* vc, bool fullscreen) {
  unsigned flags;
  if (fullscreen) {
    flags = vc->flags | VC_FLAG_FULLSCREEN;
  } else {
    flags = vc->flags & ~VC_FLAG_FULLSCREEN;
  }
  if (flags != vc->flags) {
    vc->flags = flags;
    tc_seth(&vc->textcon, vc_rows(vc));
  }
  vc_render(vc);
}

const gfx_font* vc_get_font() { return g_font; }

void vc_attach_gfx(vc_t* vc) {
  if (vc->graphics == nullptr) {
    return;
  }
  // If the size of the new gfx console doesn't match what we had been
  // attached to, we need to allocate new memory and copy the existing
  // data over.
  unsigned rows = vc->graphics->vc_gfx->height / vc->charh;
  unsigned columns = vc->graphics->vc_gfx->width / vc->charw;
  if (rows == vc->rows && columns == vc->columns) {
    return;
  }

  // allocate the new buffers
  vc_char_t* text_buf = reinterpret_cast<vc_char_t*>(calloc(1, rows * columns * sizeof(vc_char_t)));
  vc_char_t* scrollback_buf = reinterpret_cast<vc_char_t*>(
      calloc(1, vc->scrollback_rows_max * columns * sizeof(vc_char_t)));
  if (text_buf && scrollback_buf) {
    // fill new text buffer with blank characters
    size_t count = rows * columns;
    vc_char_t* ptr = text_buf;
    while (count--) {
      *ptr++ = vc_char_make(' ', vc->front_color, vc->back_color);
    }

    // Copy the most recent data from the old console to the new one. There are
    // (vc->cursor_y + 1) rows available, and we want (rows - (vc->rows - vc_rows(vc))
    // rows. Subtract to get the first row index to copy.
    unsigned old_i =
        MAX(static_cast<int>((vc->cursor_y + 1) - (rows - (vc->rows - vc_rows(vc)))), 0);
    unsigned old_data_start = old_i;
    unsigned new_i = 0;
    size_t len = (vc->columns < columns ? vc->columns : columns) * sizeof(vc_char_t);
    while (new_i < rows && old_i <= vc->cursor_y) {
      memcpy(text_buf + columns * (new_i++), vc->text_buf + vc->columns * (old_i++), len);
    }

    // copy the old scrollback buffer
    for (int i = 0; i < SCROLLBACK_ROWS; i++) {
      memcpy(scrollback_buf + columns * i, vc->scrollback_buf + vc->columns * i, len);
    }

    vc_char_t* old_text_buf = vc->text_buf;
    unsigned old_columns = vc->columns;
    free(vc->scrollback_buf);

    vc->text_buf = text_buf;
    vc->scrollback_buf = scrollback_buf;
    vc->rows = rows;
    vc->columns = columns;

    // Push any data that fell off of text_buf. Use a temporary buffer of the
    // right length to handle going to a wider console. Set it to ' 's before
    // pushing, so we don't merge data from old rows.
    if (old_data_start) {
      vc_char_t buf[columns];
      for (unsigned i = 0; i < old_data_start; i++) {
        vc_char_t* ptr = buf;
        while (ptr < buf + columns) {
          *ptr++ = vc_char_make(' ', vc->front_color, vc->back_color);
        }
        ptr = old_text_buf + i * old_columns;
        memcpy(buf, ptr, len);

        vc_tc_scrollback_buffer_push(vc, buf);
      }
    }

    free(old_text_buf);
  } else {
    // If we failed to allocate new buffers, use the old ones as best we can
    free(text_buf);
    free(scrollback_buf);

    vc->rows = MIN(vc->rows, rows);
    vc->columns = MIN(vc->columns, columns);

    printf("vc: buffer resize failed, reusing old buffers (%dx%d)\n", vc->rows, vc->columns);
  }

  vc->viewport_y = 0;
  if (vc->cursor_x >= vc->columns) {
    vc->cursor_x = vc->columns - 1;
  }
  if (static_cast<int>(vc->cursor_y) >= vc_rows(vc)) {
    vc->cursor_y = vc_rows(vc) - 1;
  }

  tc_init(&vc->textcon, vc->columns, vc_rows(vc), vc->text_buf, vc->front_color, vc->back_color,
          vc->cursor_x, vc->cursor_y);
}

zx_status_t vc_alloc(vc_t** out, const color_scheme_t* color_scheme) {
  vc_t* vc = reinterpret_cast<vc_t*>(calloc(1, sizeof(vc_t)));
  if (!vc) {
    return ZX_ERR_NO_MEMORY;
  }
  vc->fd = -1;

  vc->keymap = g_keymap;
  vc->font = vc_get_font();
  vc->charw = vc->font->width;
  vc->charh = vc->font->height;

  zx_status_t status = vc_setup(vc, color_scheme);
  if (status != ZX_OK) {
    free(vc);
    return status;
  }

  vc_attach_to_main_display(vc);
  vc_reset(vc);

  *out = vc;
  return ZX_OK;
}

void vc_free(vc_t* vc) {
  if (vc->active) {
    g_active_vc = nullptr;
    vc_set_active(0, nullptr);
  }
  if (g_active_vc) {
    vc_full_repaint(g_active_vc);
    vc_render(g_active_vc);
  }

  if (vc->fd >= 0) {
    close(vc->fd);
  }
  free(vc->text_buf);
  free(vc->scrollback_buf);
  free(vc);
}

void vc_flush(vc_t* vc) {
  if (g_vc_owns_display && vc_graphics_enabled(vc) && vc->invy1 >= 0) {
    int rows = vc_rows(vc);
    // Adjust for the current viewport position.  Convert
    // console-relative row numbers to screen-relative row numbers.
    int invalidate_y0 = MIN(vc->invy0 - vc->viewport_y, rows);
    int invalidate_y1 = MIN(vc->invy1 - vc->viewport_y, rows);
    vc_gfx_invalidate(vc->graphics, vc, 0, invalidate_y0, vc->columns,
                      invalidate_y1 - invalidate_y0);
  }
}

void vc_flush_all(vc_t* vc) {
  if (g_vc_owns_display && vc_graphics_enabled(vc)) {
    vc_gfx_invalidate_all(vc->graphics, vc);
  }
}

void vc_device_init(const gfx_font* font, const keychar_t* keymap) {
  g_font = font;
  g_keymap = keymap;
}
