/*
 * This file is part of the coreinfo project.
 *
 * 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"
#include <commonlib/timestamp_serialized.h>

#if IS_ENABLED(CONFIG_MODULE_TIMESTAMPS)

#define LINES_SHOWN 19
#define TAB_WIDTH 2

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

static unsigned long tick_freq_mhz;

static const char *timestamp_name(uint32_t id)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(timestamp_ids); i++) {
		if (timestamp_ids[i].id == id)
			return timestamp_ids[i].name;
	}

	return "<unknown>";
}

static void timestamp_set_tick_freq(unsigned long table_tick_freq_mhz)
{
	tick_freq_mhz = table_tick_freq_mhz;

	/* Honor table frequency. */
	if (tick_freq_mhz)
		return;

	tick_freq_mhz = lib_sysinfo.cpu_khz / 1000;

	if (!tick_freq_mhz) {
		fprintf(stderr, "Cannot determine timestamp tick frequency.\n");
		exit(1);
	}
}

static u64 arch_convert_raw_ts_entry(u64 ts)
{
	return ts / tick_freq_mhz;
}

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 uint64_t timestamp_print_entry(char *buffer, size_t size, uint32_t *cur,
		uint32_t id, uint64_t stamp, uint64_t prev_stamp)
{
	const char *name;
	uint64_t step_time;

	name = timestamp_name(id);
	step_time = arch_convert_raw_ts_entry(stamp - prev_stamp);

	*cur += snprintf(buffer + *cur, size, "%4d: %-45s", id, name);
	*cur += snprintf(buffer + *cur, size, "%llu",
			arch_convert_raw_ts_entry(stamp));
	if (prev_stamp) {
		*cur += snprintf(buffer + *cur, size, " (");
		*cur += snprintf(buffer + *cur, size, "%llu", step_time);
		*cur += snprintf(buffer + *cur, size, ")");
	}
	*cur += snprintf(buffer + *cur, size, "\n");

	return step_time;
}

static int timestamps_module_init(void)
{
	/* Make sure that lib_sysinfo is initialized */
	int ret = lib_get_sysinfo();

	if (ret)
		return -1;

	struct timestamp_table *timestamps = lib_sysinfo.tstamp_table;

	if (timestamps == NULL)
		return -1;

	/* Extract timestamps information */
	u64 base_time = timestamps->base_time;
	u16 max_entries = timestamps->max_entries;
	u32 n_entries = timestamps->num_entries;

	timestamp_set_tick_freq(timestamps->tick_freq_mhz);

	char *buffer;
	u32 buff_cur = 0;
	uint64_t prev_stamp;
	uint64_t total_time;

	/* Allocate a buffer big enough to contain all of the possible
	 * entries plus the other information (number entries, total time). */
	buffer = malloc((max_entries + 4) * SCREEN_X * sizeof(char));

	if (buffer == NULL)
		return -3;

	/* Write the content */
	buff_cur += snprintf(buffer, SCREEN_X, "%d entries total:\n\n",
			n_entries);

	prev_stamp = 0;
	timestamp_print_entry(buffer, SCREEN_X, &buff_cur, 0, base_time,
			prev_stamp);
	prev_stamp = base_time;

	total_time = 0;
	for (int i = 0; i < n_entries; i++) {
		uint64_t stamp;
		const struct timestamp_entry *tse = &timestamps->entries[i];

		stamp = tse->entry_stamp + base_time;
		total_time += timestamp_print_entry(buffer, SCREEN_X,
				&buff_cur, tse->entry_id, stamp, prev_stamp);
		prev_stamp = stamp;
	}

	buff_cur += snprintf(buffer + buff_cur, SCREEN_X, "\nTotal Time: ");
	buff_cur += snprintf(buffer + buff_cur, SCREEN_X, "%llu", total_time);
	buff_cur += snprintf(buffer + buff_cur, SCREEN_X, "\n");

	/* Calculate how many characters will be displayed on screen */
	u32 chars_count = calculate_chars_count(buffer, buff_cur + 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) {
		free(buffer);
		return -3;
	}

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

	free(buffer);

	return 0;
}

static int timestamps_module_redraw(WINDOW *win)
{
	print_module_title(win, "coreboot Timestamps");

	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 timestamps_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 timestamps_module = {
	.name = "Timestamps",
	.init = timestamps_module_init,
	.redraw = timestamps_module_redraw,
	.handle = timestamps_module_handle,
};

#else

struct coreinfo_module timestamps_module = {
};

#endif
