-- luacheck: globals term

local createLibTest = require('/apis/libtest');
local createTui = require('/apis/libtui');

local testlib = createLibTest({ ... });

local function fakeEventLoop()
  local onStart = nil;
  local onStop = nil;

  return {
    onStart = function(fn) onStart = fn; end,
    onStop = function(fn) onStop = fn; end,
    register = function() end,
    startLoop = function()
      if onStart then
        onStart();
      end
      return true;
    end,
    stopLoop = function()
      if onStop then
        onStop();
      end
    end,
    isRunningLoop = function()
      return false;
    end,
  };
end

local function withFakeTerm(fn)
  local originalTerm = term;
  local writes = {};
  local state = {
    textColor = colors.white,
    bgColor = colors.black,
    cursorX = 1,
    cursorY = 1,
    cursorBlink = false,
    width = 20,
    height = 5,
  };

  term = {
    setCursorBlink = function(value) state.cursorBlink = value; end,
    setTextColor = function(value) state.textColor = value; end,
    setBackgroundColor = function(value) state.bgColor = value; end,
    clear = function() writes[#writes + 1] = { kind = 'clear' }; end,
    getTextColor = function() return state.textColor; end,
    getBackgroundColor = function() return state.bgColor; end,
    getCursorPos = function() return state.cursorX, state.cursorY; end,
    getCursorBlink = function() return state.cursorBlink; end,
    setCursorPos = function(x, y)
      state.cursorX = x;
      state.cursorY = y;
    end,
    getSize = function() return state.width, state.height; end,
    write = function(text)
      writes[#writes + 1] = {
        kind = 'write',
        text = text,
        x = state.cursorX,
        y = state.cursorY,
        color = state.textColor,
        bgColor = state.bgColor,
      };
      state.cursorX = state.cursorX + string.len(text);
    end,
  };

  local ok, err = pcall(fn, writes, state);
  term = originalTerm;

  if not ok then
    error(err, 0);
  end
end

testlib.test('text nodes pad utf8 text by characters', function()
  withFakeTerm(function(writes)
    local ui = createTui(fakeEventLoop());
    ui.render(ui.Box({
      children = {
        ui.Box({
          width = 3,
          height = 1,
          children = { ui.Text('é') },
        }),
      },
    }));

    local found = false;
    for _, item in ipairs(writes) do
      if item.kind == 'write' and item.text == 'é  ' then
        found = true;
        break;
      end
    end

    testlib.assertTrue(found, 'expected padded utf8 text');
  end);
end);

testlib.test('box borders keep utf8 titles intact', function()
  withFakeTerm(function(writes)
    local ui = createTui(fakeEventLoop());
    ui.render(ui.Box({
      children = {
        ui.Box({
          width = 5,
          height = 3,
          border = true,
          title = 'Ç',
          children = {},
        }),
      },
    }));

    local found = false;
    for _, item in ipairs(writes) do
      if item.kind == 'write' and item.text == '+ Ç +' then
        found = true;
        break;
      end
    end

    testlib.assertTrue(found, 'expected utf8 border title');
  end);
end);

testlib.run();
