/*
 * This file is part of the coreinfo project.
 *
 * Copyright (C) 2008 Uwe Hermann <uwe@hermann-uwe.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include "coreinfo.h"

#if IS_ENABLED(CONFIG_MODULE_BOOTLOG)

#define LINES_SHOWN 19
#define TAB_WIDTH 2


/* Globals that are used for tracking screen state */
static char *g_buf = NULL;
static s32 g_line = 0;
static s32 g_lines_count = 0;
static s32 g_max_cursor_line = 0;


/* Copied from libpayload/drivers/cbmem_console.c */
struct cbmem_console {
	u32 size;
	u32 cursor;
	u8 body[0];
} __attribute__ ((__packed__));


static u32 char_width(char c, u32 cursor, u32 screen_width)
{
	if (c == '\n') {
		return screen_width - (cursor % screen_width);
	} else if (c == '\t') {
		return TAB_WIDTH;
	} else if (isprint(c)) {
		return 1;
	}

	return 0;
}

static u32 calculate_chars_count(char *str, u32 str_len, u32 screen_width, u32 screen_height)
{
	u32 i, count = 0;

	for (i = 0; i < str_len; i++) {
		count += char_width(str[i], count, screen_width);
	}

	/* Ensure that 'count' can occupy at least the whole screen */
	if (count < screen_width * screen_height) {
		count = screen_width * screen_height;
	}

	/* Pad to line end */
	if (count % screen_width != 0) {
		count += screen_width - (count % screen_width);
	}

	return count;
}

/*
 * This method takes an input buffer and sanitizes it for display, which means:
 *  - '\n' is converted to spaces until end of line
 *  - Tabs are converted to spaces of size TAB_WIDTH
 *  - Only printable characters are preserved
 */
static int sanitize_buffer_for_display(char *str, u32 str_len, char *out, u32 out_len, u32 screen_width)
{
	u32 cursor = 0;
	u32 i;

	for (i = 0; i < str_len && cursor < out_len; i++) {
		u32 width = char_width(str[i], cursor, screen_width);
		if (width == 1) {
			out[cursor++] = str[i];
		} else if (width > 1) {
			while (width-- && cursor < out_len) {
				out[cursor++] = ' ';
			}
		}
	}

	/* Fill the rest of the out buffer with spaces */
	while (cursor < out_len) {
		out[cursor++] = ' ';
	}

	return 0;
}

static int bootlog_module_init(void)
{
	/* Make sure that lib_sysinfo is initialized */
	int ret = lib_get_sysinfo();
	if (ret) {
		return -1;
	}

	struct cbmem_console *console = lib_sysinfo.cbmem_cons;
	if (console == NULL) {
		return -1;
	}
	/* Extract console information */
	char *buffer = (char *)(&(console->body));
	u32 buffer_size = console->size;
	u32 cursor = console->cursor;

	/* The cursor may be bigger than buffer size when the buffer is full */
	if (cursor >= buffer_size) {
		cursor = buffer_size - 1;
	}

	/* Calculate how much characters will be displayed on screen */
	u32 chars_count = calculate_chars_count(buffer, cursor + 1, SCREEN_X, LINES_SHOWN);

	/* Sanity check, chars_count must be padded to full line */
	if (chars_count % SCREEN_X != 0) {
		return -2;
	}

	g_lines_count = chars_count / SCREEN_X;
	g_max_cursor_line = MAX(g_lines_count - 1 - LINES_SHOWN, 0);

	g_buf = malloc(chars_count);
	if (!g_buf) {
		return -3;
	}

	if (sanitize_buffer_for_display(buffer, cursor + 1,
									g_buf, chars_count,
									SCREEN_X) < 0) {
		free(g_buf);
		g_buf = NULL;
		return -4;
	}

	/* TODO: Maybe a _cleanup hook where we call free()? */

	return 0;
}

static int bootlog_module_redraw(WINDOW *win)
{
	print_module_title(win, "Coreboot Bootlog");

	if (!g_buf) {
		return -1;
	}

	int x = 0, y = 0;
	char *tmp = g_buf + g_line * SCREEN_X;

	for (y = 0; y < LINES_SHOWN; y++) {
		for (x = 0; x < SCREEN_X; x++) {
			mvwaddch(win, y + 2, x, *tmp);
			tmp++;
		}

	}

	return 0;
}

static int bootlog_module_handle(int key)
{
	if (!g_buf) {
		return 0;
	}

	switch (key) {
	case KEY_DOWN:
		g_line++;
		break;
	case KEY_UP:
		g_line--;
		break;
	case KEY_NPAGE: /* Page up */
		g_line -= LINES_SHOWN;
		break;
	case KEY_PPAGE: /* Page down */
		g_line += LINES_SHOWN;
		break;
	}

	if (g_line < 0)
		g_line = 0;

	if (g_line > g_max_cursor_line)
		g_line = g_max_cursor_line;

	return 1;
}

struct coreinfo_module bootlog_module = {
	.name = "Bootlog",
	.init = bootlog_module_init,
	.redraw = bootlog_module_redraw,
	.handle = bootlog_module_handle,
};

#else

struct coreinfo_module bootlog_module = {
};

#endif
