// 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 = 0;
                tc->bg = 15;
            } 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 = 0;
            } else if (n == 49) { // default bg
                tc->bg = 15;
            }
        }
        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 Hilight 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->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 fixup 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);
}
