// 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 <stdlib.h>
#include <string.h>
#include <sys/param.h>

#include <zircon/process.h>
#include <zircon/syscalls.h>

#include <fbl/auto_lock.h>
#include <lib/gfx-font-data/gfx-font-data.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))

// shared with vc-gfx.cpp
extern gfx_surface* vc_gfx;
extern gfx_surface* vc_tb_gfx;
extern const gfx_font* vc_font;

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

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_gfx) {
        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, 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, 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_gfx) {
        gfx_copyrect(vc_gfx, 0, y_src * vc->charh,
                     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_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_gfx) {
            vc_gfx_invalidate_status();
        }
        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_gfx) {
        gfx_fillrect(vc_gfx, 0, 0, vc_gfx->width, 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_gfx) {
        vc_gfx_invalidate_all(vc);
    }
}

void vc_status_clear() {
    if (g_vc_owns_display && vc_gfx) {
        gfx_fillrect(vc_tb_gfx, 0, 0,
                     vc_tb_gfx->width, vc_tb_gfx->height,
                     default_palette[STATUS_COLOR_BG]);
    }
}

void vc_status_commit() {
    if (g_vc_owns_display && vc_gfx) {
        vc_gfx_invalidate_status();
    }
}

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

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

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

void vc_full_repaint(vc_t* vc) {
    if (g_vc_owns_display && vc_gfx) {
        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_gfx) {
        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_gfx, 0, diff_abs * vc->charh,
                         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_gfx, 0, 0, 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() {
    char* fname = getenv("virtcon.font");
    if (fname) {
        if (!strcmp(fname, "9x16")) {
            return &gfx_font_9x16;
        } else if (!strcmp(fname, "18x32")) {
            return &gfx_font_18x32;
        } else {
            printf("gfxconsole: no such font '%s'\n", fname);
        }
    }
    return &gfx_font_9x16;
}

void vc_attach_gfx(vc_t* vc) {
    // 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_gfx->height / vc->charh;
    unsigned columns = 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 = qwerty_map;
    char* keys = getenv("virtcon.keymap");
    if (keys) {
        if (!strcmp(keys, "qwerty")) {
            vc->keymap = qwerty_map;
        } else if (!strcmp(keys, "dvorak")) {
            vc->keymap = dvorak_map;
        } else {
            printf("gfxconsole: no such keymap '%s'\n", keys);
        }
    }

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

    if (vc_gfx) {
        vc_attach_gfx(vc);
    }
    vc_reset(vc);

    *out = vc;
    return ZX_OK;
}

void vc_free(vc_t* 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_gfx && 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, 0, invalidate_y0,
                          vc->columns, invalidate_y1 - invalidate_y0);
    }
}

void vc_flush_all(vc_t* vc) {
    if (g_vc_owns_display && vc_gfx) {
        vc_gfx_invalidate_all(vc);
    }
}
