// Copyright 2017 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 <sys/param.h>

#include <memory>

#include <gfx/gfx.h>
#include <zxtest/zxtest.h>

#include "vc.h"

// The graphics used for testing.
vc_gfx_t main_test_graphics = {};
void vc_attach_to_main_display(vc_t* vc) {
  vc->graphics = &main_test_graphics;
  vc_attach_gfx(vc);
}

// This is needed to satisfy a reference from vc_handle_device_control_keys
// in vc-input.cpp but the code path to that reference is dead in this test.
void vc_toggle_framebuffer() { __builtin_trap(); }

bool g_vc_owns_display = true;

namespace {

void invalidate_callback(void* cookie, int x, int y, int w, int h) {}

void movecursor_callback(void* cookie, int x, int y) {}

void push_scrollback_line_callback(void* cookie, int y) {}

void copy_lines_callback(void* cookie, int y_dest, int y_src, int line_count) {
  auto* tc = reinterpret_cast<textcon_t*>(cookie);
  tc_copy_lines(tc, y_dest, y_src, line_count);
}

void setparam_callback(void* cookie, int param, uint8_t* arg, size_t arglen) {}

// Helper for initializing and testing console instances.  This actually
// creates two console instances:
//
//  * A textcon_t (non-graphical), for testing character-level output.
//  * A vc_t (graphical), for testing incremental updates to the
//    gfx_surface.
//
// In principle, we could test the character-level output via the textcon_t
// that the vc_t creates internally.  However, using our own
// separate textcon_t instance helps check that textcon_t can be used on
// its own, outside of vc_t.
class TextconHelper {
 public:
  TextconHelper(uint32_t size_x, uint32_t size_y,
                const color_scheme_t* color_scheme = &color_schemes[kDefaultColorScheme])
      : size_x(size_x), size_y(size_y) {
    // Create a textcon_t.
    textbuf = new vc_char_t[size_x * size_y];
    textcon.cookie = &textcon;
    textcon.invalidate = invalidate_callback;
    textcon.movecursor = movecursor_callback;
    textcon.push_scrollback_line = push_scrollback_line_callback;
    textcon.copy_lines = copy_lines_callback;
    textcon.setparam = setparam_callback;
    tc_init(&textcon, size_x, size_y, textbuf, color_scheme->front, color_scheme->back, 0, 0);
    // Initialize buffer contents, since this is currently done
    // outside of textcon.cpp in vc-device.cpp.
    for (size_t i = 0; i < size_x * size_y; ++i)
      textbuf[i] = ' ';

    // Create a vc_t with the same size in characters.
    const gfx_font* font = vc_get_font();
    int pixels_x = font->width * size_x;
    int pixels_y = font->height * (size_y + 1);  // Add 1 for status line.
    // Add margins that aren't large enough to fit a whole column or
    // row at the right and bottom.  This tests incremental update of
    // anything that might be displayed in the margins.
    pixels_x += font->width - 1;
    pixels_y += font->height - 1;
    vc_surface = gfx_create_surface(nullptr, pixels_x, pixels_y, /* stride= */ pixels_x,
                                    ZX_PIXEL_FORMAT_RGB_565, 0);
    EXPECT_TRUE(vc_surface);
    // This takes ownership of vc_surface.
    EXPECT_OK(vc_init_gfx(&main_test_graphics, vc_surface));
    EXPECT_OK(vc_alloc(&vc_dev, color_scheme));
    EXPECT_EQ(vc_dev->columns, size_x);
    EXPECT_EQ(vc_rows(vc_dev), static_cast<int>(size_y));
    // Mark the console as active so that display updates get
    // propagated to vc_surface.
    vc_dev->active = true;
    // Propagate the initial display contents to vc_surface.
    vc_full_repaint(vc_dev);
    vc_gfx_invalidate_all(&main_test_graphics, vc_dev);
  }

  ~TextconHelper() {
    delete[] textbuf;
    vc_free(vc_dev);
    vc_free_gfx(&main_test_graphics);
  }

  // Takes a snapshot of the vc_t's display.
  class DisplaySnapshot {
   public:
    DisplaySnapshot(TextconHelper* helper)
        : helper_(helper), snapshot_(new uint8_t[helper->vc_surface->len]) {
      memcpy(snapshot_.get(), helper->vc_surface->ptr, helper->vc_surface->len);
    }

    // Returns whether the vc_t's display changed since the
    // snapshot was taken.
    bool ChangedSinceSnapshot() {
      return memcmp(snapshot_.get(), helper_->vc_surface->ptr, helper_->vc_surface->len) != 0;
    }

    std::unique_ptr<char[]> ComparisonString() {
      vc_t* vc_dev = helper_->vc_dev;
      gfx_surface* vc_surface = helper_->vc_surface;
      // Add 1 to these sizes to account for the margins.
      uint32_t cmp_size_x = vc_dev->columns + 1;
      uint32_t cmp_size_y = vc_dev->rows + 1;
      uint32_t size_in_chars = cmp_size_x * cmp_size_y;

      std::unique_ptr<bool[]> diffs(new bool[size_in_chars]);
      for (uint32_t i = 0; i < size_in_chars; ++i)
        diffs[i] = false;

      for (uint32_t i = 0; i < vc_surface->len; ++i) {
        if (static_cast<uint8_t*>(vc_surface->ptr)[i] != snapshot_[i]) {
          uint32_t pixel_index = i / vc_surface->pixelsize;
          uint32_t x_pixels = pixel_index % vc_surface->stride;
          uint32_t y_pixels = pixel_index / vc_surface->stride;
          uint32_t x_chars = x_pixels / vc_dev->charw;
          uint32_t y_chars = y_pixels / vc_dev->charh;
          EXPECT_LT(x_chars, cmp_size_x);
          EXPECT_LT(y_chars, cmp_size_y);
          diffs[x_chars + y_chars * cmp_size_x] = true;
        }
      }

      // Build a string showing the differences.  If we had
      // std::string or equivalent, we'd use that here.
      size_t string_size = (cmp_size_x + 3) * cmp_size_y + 1;
      std::unique_ptr<char[]> string(new char[string_size]);
      char* ptr = string.get();
      for (uint32_t y = 0; y < cmp_size_y; ++y) {
        *ptr++ = '|';
        for (uint32_t x = 0; x < cmp_size_x; ++x) {
          bool diff = diffs[x + y * cmp_size_x];
          *ptr++ = diff ? 'D' : '-';
        }
        *ptr++ = '|';
        *ptr++ = '\n';
      }
      *ptr++ = 0;
      EXPECT_EQ(ptr, string.get() + string_size);
      return string;
    }

    // Prints a representation of which characters in the vc_t's
    // display changed since the snapshot was taken.
    void PrintComparison() { printf("%s", ComparisonString().get()); }

   private:
    TextconHelper* helper_;
    std::unique_ptr<uint8_t[]> snapshot_;
  };

  void InvalidateAllGraphics() {
    vc_full_repaint(vc_dev);
    vc_gfx_invalidate_all(&main_test_graphics, vc_dev);
  }

  void PutString(const char* str) {
    for (const char* ptr = str; *ptr; ++ptr)
      textcon.putc(&textcon, *ptr);

    vc_write(vc_dev, str, strlen(str), 0);
    // Test that the incremental update of the display was correct.  We
    // do that by refreshing the entire display, and checking that
    // there was no change.
    DisplaySnapshot copy(this);
    InvalidateAllGraphics();
    if (copy.ChangedSinceSnapshot()) {
      copy.PrintComparison();
      EXPECT_TRUE(false, "Display contents changed");
    }
  }

  void AssertTextbufLineContains(vc_char_t* buf, int line_num, const char* str) {
    size_t len = strlen(str);
    EXPECT_LE(len, size_x);
    for (size_t i = 0; i < len; ++i)
      EXPECT_EQ(str[i], vc_char_get_char(buf[size_x * line_num + i]));
    // The rest of the line should contain spaces.
    for (size_t i = len; i < size_x; ++i)
      EXPECT_EQ(' ', vc_char_get_char(buf[size_x * line_num + i]));
  }

  void AssertLineContains(int line_num, const char* str) {
    AssertTextbufLineContains(textbuf, line_num, str);
    AssertTextbufLineContains(vc_dev->text_buf, line_num, str);
  }

  uint32_t size_x;
  uint32_t size_y;

  vc_char_t* textbuf;
  textcon_t textcon = {};

  gfx_surface* vc_surface;
  vc_t* vc_dev;
};

TEST(GfxConsoleTextbufTests, Simple) {
  TextconHelper tc(10, 5);
  tc.PutString("Hello");
  tc.AssertLineContains(0, "Hello");
  tc.AssertLineContains(1, "");
}

// This tests the DisplaySnapshot test helper above.  If we write directly
// to vc_dev's text buffer without invalidating the display, the test
// machinery should detect which characters in the display were not updated
// properly.
TEST(GfxConsoleTextbufTests, DisplayUpdateComparison) {
  TextconHelper tc(10, 3);
  // Write some characters directly into the text buffer.
  auto SetChar = [&](int x, int y, char ch) {
    tc.vc_dev->text_buf[x + y * tc.size_x] = vc_char_make(ch, tc.textcon.fg, tc.textcon.bg);
  };
  SetChar(2, 1, 'x');
  SetChar(3, 1, 'y');
  SetChar(6, 1, 'z');

  // Check that these characters in the display are detected as not
  // properly updated.
  TextconHelper::DisplaySnapshot snapshot(&tc);
  tc.InvalidateAllGraphics();
  EXPECT_TRUE(snapshot.ChangedSinceSnapshot());
  const char* expected =
      "|-----------|\n"  // Console status line
      "|-----------|\n"  // Cursor at left was painted during tc init
      "|--DD--D----|\n"  // Chars set by SetChar() above
      "|-----------|\n"
      "|-----------|\n";  // Bottom margin
  EXPECT_EQ(strcmp(snapshot.ComparisonString().get(), expected), 0);
}

// This tests updating the display with all of the different color schemes. This
// catches that the tc and the vcs set their color schemes correctly. If
// something goes wrong, either all of the chars will appear to be changed or
// none will be changed.
TEST(GfxConsoleTextbufTests, DisplayColorSchemes) {
  int colors[] = {kDarkColorScheme, kLightColorScheme, kSpecialColorScheme};
  for (size_t c = 0; c < countof(colors); c++) {
    TextconHelper tc(10, 3, &color_schemes[colors[c]]);
    // Write some characters directly into the text buffer.
    auto SetChar = [&](int x, int y, char ch) {
      tc.vc_dev->text_buf[x + y * tc.size_x] = vc_char_make(ch, tc.textcon.fg, tc.textcon.bg);
    };
    SetChar(2, 1, 'x');
    SetChar(3, 1, 'y');
    SetChar(6, 1, 'z');

    // Check that these characters in the display are detected as not
    // properly updated.
    TextconHelper::DisplaySnapshot snapshot(&tc);
    tc.InvalidateAllGraphics();
    EXPECT_TRUE(snapshot.ChangedSinceSnapshot());
    const char* expected =
        "|-----------|\n"  // Console status line
        "|-----------|\n"  // Cursor at left was painted during tc init
        "|--DD--D----|\n"  // Chars set by SetChar() above
        "|-----------|\n"
        "|-----------|\n";  // Bottom margin
    EXPECT_EQ(strcmp(snapshot.ComparisonString().get(), expected), 0);
  }
}

TEST(GfxConsoleTextbufTests, Wrapping) {
  TextconHelper tc(10, 5);
  tc.PutString("Hello world! More text here.");
  tc.AssertLineContains(0, "Hello worl");
  tc.AssertLineContains(1, "d! More te");
  tc.AssertLineContains(2, "xt here.");
}

TEST(GfxConsoleTextbufTests, Tabs) {
  TextconHelper tc(80, 40);
  tc.PutString("\tA\n");
  tc.PutString(" \tB\n");
  tc.PutString("       \tC\n");   // 7 spaces
  tc.PutString("        \tD\n");  // 8 spaces
  tc.AssertLineContains(0, "        A");
  tc.AssertLineContains(1, "        B");
  tc.AssertLineContains(2, "        C");
  tc.AssertLineContains(3, "                D");
}

TEST(GfxConsoleTextbufTests, BackspaceMovesCursor) {
  TextconHelper tc(10, 5);
  tc.PutString("ABCDEF\b\b\b\bxy");
  // Backspace only moves the cursor and does not erase, so "EF" is left
  // in place.
  tc.AssertLineContains(0, "ABxyEF");
}

TEST(GfxConsoleTextbufTests, BackspaceAtStartOfLine) {
  TextconHelper tc(10, 5);
  tc.PutString("Foo\n\bBar");
  // When the cursor is at the start of a line, backspace has no effect.
  tc.AssertLineContains(0, "Foo");
  tc.AssertLineContains(1, "Bar");
}

TEST(GfxConsoleTextbufTests, DeleteChars) {
  TextconHelper tc(20, 10);

  tc.PutString("123456");
  // Move the cursor to be over the "3".
  tc.PutString("\b\b\b\b");
  // Delete 2 characters to the right of the cursor, using the "DCH"
  // escape sequence.  Any characters beyond that, on the right, are
  // moved to the left by 2 characters.  This escape sequence is a
  // reduced test from a fuzzer-discovered example (see ZX-2936).  This
  // used to trigger an assertion failure.
  tc.PutString("\x1b[2P");
  tc.AssertLineContains(0, "1256");
}

TEST(GfxConsoleTextbufTests, DeleteCharsOverflow) {
  TextconHelper tc(6, 10);

  // Fill the width of the console, leaving the cursor on the next line.
  tc.PutString("123456");
  // Move the cursor to be over the "3", to position (y+1,x+1) = (1,3).
  tc.PutString("\x1b[1;3H");
  // Request deleting 5 characters to the right of the cursor, using
  // the "DCH" escape sequence.  This tests an overflow case,
  // because there are only 4 characters to the right of the cursor.
  tc.PutString("\x1b[5P");
  tc.AssertLineContains(0, "12");
}

TEST(GfxConsoleTextbufTests, ScrollUp) {
  TextconHelper tc(10, 4);
  tc.PutString("AAA\nBBB\nCCC\nDDD\n");
  tc.AssertLineContains(0, "BBB");
  tc.AssertLineContains(1, "CCC");
  tc.AssertLineContains(2, "DDD");
  tc.AssertLineContains(3, "");
  EXPECT_EQ(vc_get_scrollback_lines(tc.vc_dev), 1);
}

// Same as scroll_up(), but using ESC E (NEL) instead of "\n".
TEST(GfxConsoleTextbufTests, ScrollUpNel) {
  TextconHelper tc(10, 4);
  tc.PutString(
      "AAA"
      "\x1b"
      "E"
      "BBB"
      "\x1b"
      "E"
      "CCC"
      "\x1b"
      "E"
      "DDD"
      "\x1b"
      "E");
  tc.AssertLineContains(0, "BBB");
  tc.AssertLineContains(1, "CCC");
  tc.AssertLineContains(2, "DDD");
  tc.AssertLineContains(3, "");
  EXPECT_EQ(vc_get_scrollback_lines(tc.vc_dev), 1);
}

TEST(GfxConsoleTextbufTests, InsertLines) {
  TextconHelper tc(10, 5);
  tc.PutString("AAA\nBBB\nCCC\nDDD\nEEE");
  tc.PutString("\x1b[2A");  // Move the cursor up 2 lines
  tc.PutString("\x1b[2L");  // Insert 2 lines
  tc.PutString("Z");        // Output char to show where the cursor ends up
  tc.AssertLineContains(0, "AAA");
  tc.AssertLineContains(1, "BBB");
  tc.AssertLineContains(2, "   Z");
  tc.AssertLineContains(3, "");
  tc.AssertLineContains(4, "CCC");
  EXPECT_EQ(vc_get_scrollback_lines(tc.vc_dev), 0);
}

TEST(GfxConsoleTextbufTests, DeleteLines) {
  TextconHelper tc(10, 5);
  tc.PutString("AAA\nBBB\nCCC\nDDD\nEEE");
  tc.PutString("\x1b[2A");  // Move the cursor up 2 lines
  tc.PutString("\x1b[2M");  // Delete 2 lines
  tc.PutString("Z");        // Output char to show where the cursor ends up
  tc.AssertLineContains(0, "AAA");
  tc.AssertLineContains(1, "BBB");
  tc.AssertLineContains(2, "EEEZ");
  tc.AssertLineContains(3, "");
  tc.AssertLineContains(4, "");
  // TODO(mseaborn): We probably don't want to be adding the deleted
  // lines to the scrollback in this case, because they are not from the
  // top of the console.
  EXPECT_EQ(vc_get_scrollback_lines(tc.vc_dev), 2);
}

// Test for a bug where this would cause an out-of-bounds array access.
TEST(GfxConsoleTextbufTests, InsertLinesMany) {
  TextconHelper tc(10, 5);
  tc.PutString("AAA\nBBB");
  tc.PutString("\x1b[999L");  // Insert 999 lines
  tc.PutString("Z");          // Output char to show where the cursor ends up
  tc.AssertLineContains(0, "AAA");
  tc.AssertLineContains(1, "   Z");
}

// Test for a bug where this would cause an out-of-bounds array access.
TEST(GfxConsoleTextbufTests, DeleteLinesMany) {
  TextconHelper tc(10, 5);
  tc.PutString("AAA\nBBB");
  tc.PutString("\x1b[999M");  // Delete 999 lines
  tc.PutString("Z");          // Output char to show where the cursor ends up
  tc.AssertLineContains(0, "AAA");
  tc.AssertLineContains(1, "   Z");
}

// Check that passing a huge parameter via "insert lines" completes in a
// reasonable amount of time.  (We don't check the time here but we assume
// that someone will notice if this takes a long time.)
TEST(GfxConsoleTextbufTests, InsertLinesHuge) {
  TextconHelper tc(10, 5);
  tc.PutString("AAA\nBBB");
  tc.PutString("\x1b[2000000000L");  // Insert lines
  tc.PutString("Z");                 // Output char to show where the cursor ends up
  tc.AssertLineContains(0, "AAA");
  tc.AssertLineContains(1, "   Z");
}

// Check that passing a huge parameter via "delete lines" completes in a
// reasonable amount of time.  (We don't check the time here but we assume
// that someone will notice if this takes a long time.)
TEST(GfxConsoleTextbufTests, DeleteLinesHuge) {
  TextconHelper tc(10, 5);
  tc.PutString("AAA\nBBB");
  tc.PutString("\x1b[200000000M");  // Delete lines
  tc.PutString("Z");                // Output char to show where the cursor ends up
  tc.AssertLineContains(0, "AAA");
  tc.AssertLineContains(1, "   Z");
}

TEST(GfxConsoleTextbufTests, MoveCursorUpAndScroll) {
  TextconHelper tc(10, 4);
  tc.PutString("AAA\nBBB\nCCC\nDDD");
  tc.PutString(
      "\x1bM"
      "1");  // Move cursor up; print char
  tc.PutString(
      "\x1bM"
      "2");  // Move cursor up; print char
  tc.PutString(
      "\x1bM"
      "3");  // Move cursor up; print char
  tc.PutString(
      "\x1bM"
      "4");  // Move cursor up; print char
  tc.AssertLineContains(0, "      4");
  tc.AssertLineContains(1, "AAA  3");
  tc.AssertLineContains(2, "BBB 2");
  tc.AssertLineContains(3, "CCC1");
}

TEST(GfxConsoleTextbufTests, MoveCursorDownAndScroll) {
  TextconHelper tc(10, 4);
  tc.PutString(
      "1"
      "\x1b"
      "D");  // Print char; move cursor down
  tc.PutString(
      "2"
      "\x1b"
      "D");  // Print char; move cursor down
  tc.PutString(
      "3"
      "\x1b"
      "D");  // Print char; move cursor down
  tc.PutString(
      "4"
      "\x1b"
      "D");  // Print char; move cursor down
  tc.PutString("5");
  tc.AssertLineContains(0, " 2");
  tc.AssertLineContains(1, "  3");
  tc.AssertLineContains(2, "   4");
  tc.AssertLineContains(3, "    5");
}

TEST(GfxConsoleTextbufTests, CursorHideAndShow) {
  TextconHelper tc(10, 4);
  ASSERT_FALSE(tc.vc_dev->hide_cursor);
  tc.PutString("\x1b[?25l");  // Hide cursor
  ASSERT_TRUE(tc.vc_dev->hide_cursor);
  tc.PutString("\x1b[?25h");  // Show cursor
  ASSERT_FALSE(tc.vc_dev->hide_cursor);
}

// This tests for a bug: If the cursor was positioned over a character when
// we scroll up, that character would get erased.
TEST(GfxConsoleTextbufTests, CursorScrollBug) {
  TextconHelper tc(10, 3);
  // Move the cursor to the bottom line.
  tc.PutString("\n\n\n");
  // Scroll down when the cursor is over "C".
  tc.PutString("ABCDE\b\b\b\n");
}

// Test for a bug where scrolling the console viewport by a large delta
// (e.g. going from the top to the bottom) can crash due to out-of-bounds
// memory accesses.
TEST(GfxConsoleTextbufTests, ScrollViewportByLargeDelta) {
  TextconHelper tc(2, 2);
  tc.PutString("\n");
  for (int lines = 1; lines < 100; ++lines) {
    tc.PutString("\n");

    // Scroll up, to show older lines.
    vc_scroll_viewport_top(tc.vc_dev);
    EXPECT_EQ(tc.vc_dev->viewport_y, -lines);

    // Scroll down, to show newer lines.
    vc_scroll_viewport_bottom(tc.vc_dev);
    EXPECT_EQ(tc.vc_dev->viewport_y, 0);
  }
}

// When the console is displaying only the main console region (and no
// scrollback), the console should keep displaying that as new lines are
// outputted.
TEST(GfxConsoleTextbufTests, ViewportScrollingFollowsBottom) {
  TextconHelper tc(1, 1);
  for (unsigned i = 0; i < tc.vc_dev->scrollback_rows_max * 2; ++i) {
    EXPECT_EQ(tc.vc_dev->viewport_y, 0);
    tc.PutString("\n");
  }
}

// When the console is displaying some of the scrollback buffer, then as
// new lines are outputted, the console should scroll the viewpoint to keep
// displaying the same point, unless we're at the top of the scrollback
// buffer.
TEST(GfxConsoleTextbufTests, ViewportScrollingFollowsScrollback) {
  TextconHelper tc(1, 1);
  // Add 3 lines to the scrollback buffer.
  tc.PutString("\n\n\n");
  vc_scroll_viewport(tc.vc_dev, -2);

  EXPECT_EQ(tc.vc_dev->viewport_y, -2);
  int limit = tc.vc_dev->scrollback_rows_max;
  for (int line = 3; line < limit * 2; ++line) {
    // Output different strings on each line in order to test that the
    // display is updated consistently when the console starts dropping
    // lines from the scrollback region.
    char str[3] = {static_cast<char>('0' + (line % 10)), '\n', '\0'};
    tc.PutString(str);
    EXPECT_EQ(tc.vc_dev->viewport_y, -MIN(line, limit));
  }
}

TEST(GfxConsoleTextbufTests, OutputWhenViewportScrolled) {
  TextconHelper tc(10, 3);
  // Line 1 will move into the scrollback region.
  tc.PutString("1\n 2\n  3\n   4");
  EXPECT_EQ(tc.vc_dev->viewport_y, 0);
  vc_scroll_viewport_top(tc.vc_dev);

  EXPECT_EQ(tc.vc_dev->viewport_y, -1);
  // Check redrawing consistency.
  tc.PutString("");

  // Test that output updates the display correctly when the viewport is
  // scrolled.  Using two separate PutString() calls here was necessary
  // for reproducing an incremental update bug.
  tc.PutString("\x1b[1;1f");  // Move to top left
  tc.PutString("Epilobium");
  tc.AssertLineContains(0, "Epilobium");
  tc.AssertLineContains(1, "  3");
  tc.AssertLineContains(2, "   4");

  // Test that erasing also updates the display correctly.  This
  // changes the console contents without moving the cursor.
  tc.PutString("\b\b\b\b");  // Move cursor left 3 chars
  tc.PutString("\x1b[1K");   // Erase to beginning of line
  tc.AssertLineContains(0, "      ium");
  tc.AssertLineContains(1, "  3");
  tc.AssertLineContains(2, "   4");
}

TEST(GfxConsoleTextbufTests, ScrollingWhenViewportScrolled) {
  TextconHelper tc(10, 3);
  // Line 1 will move into the scrollback region.
  tc.PutString("1\n 2\n  3\n   4");
  EXPECT_EQ(tc.vc_dev->viewport_y, 0);
  vc_scroll_viewport_top(tc.vc_dev);
  EXPECT_EQ(tc.vc_dev->viewport_y, -1);
  // Check redrawing consistency.
  tc.PutString("");

  // Test that the display is updated correctly when we scroll.
  tc.PutString("\n5");
  tc.AssertLineContains(0, "  3");
  tc.AssertLineContains(1, "   4");
  tc.AssertLineContains(2, "5");
}

// Test that vc_get_scrollback_lines() gives the correct results.
TEST(GfxConsoleTextbufTests, ScrollbackLinesCount) {
  TextconHelper tc(10, 3);
  tc.PutString("\n\n");

  // Reduce the scrollback limit to make the test faster.
  const int kLimit = 20;
  EXPECT_LE(kLimit, tc.vc_dev->scrollback_rows_max);
  tc.vc_dev->scrollback_rows_max = kLimit;

  for (int lines = 1; lines < kLimit * 4; ++lines) {
    tc.PutString("\n");
    EXPECT_EQ(MIN(lines, kLimit), vc_get_scrollback_lines(tc.vc_dev));
  }
}

// Test that the scrollback lines have the correct contents.
TEST(GfxConsoleTextbufTests, ScrollbackLinesContents) {
  // Use a 1-row-high console, which simplifies this test.
  TextconHelper tc(3, 1);

  // Reduce the scrollback limit to make the test faster.
  const int kLimit = 20;
  EXPECT_LE(kLimit, tc.vc_dev->scrollback_rows_max);
  tc.vc_dev->scrollback_rows_max = kLimit;

  vc_char_t test_val = 0;
  for (int lines = 1; lines <= kLimit; ++lines) {
    tc.vc_dev->text_buf[0] = test_val++;
    tc.PutString("\n");

    EXPECT_EQ(lines, vc_get_scrollback_lines(tc.vc_dev));
    for (int i = 0; i < lines; ++i)
      EXPECT_EQ(i, vc_get_scrollback_line_ptr(tc.vc_dev, i)[0]);
  }
  for (int lines = 0; lines < kLimit * 3; ++lines) {
    tc.vc_dev->text_buf[0] = test_val++;
    tc.PutString("\n");

    EXPECT_EQ(kLimit, vc_get_scrollback_lines(tc.vc_dev));
    for (int i = 0; i < kLimit; ++i) {
      EXPECT_EQ(test_val + i - kLimit, vc_get_scrollback_line_ptr(tc.vc_dev, i)[0]);
    }
  }
}

}  // namespace
