/*
 * This file is part of the coreinfo project.
 *
 * Copyright (C) 2008 Advanced Micro Devices, Inc.
 *
 * 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"

#define KEY_ESC 27

extern struct coreinfo_module cpuinfo_module;
extern struct coreinfo_module pci_module;
extern struct coreinfo_module coreboot_module;
extern struct coreinfo_module multiboot_module;
extern struct coreinfo_module nvram_module;
extern struct coreinfo_module bootlog_module;
extern struct coreinfo_module ramdump_module;
extern struct coreinfo_module cbfs_module;
extern struct coreinfo_module timestamps_module;

struct coreinfo_module *system_modules[] = {
#if CONFIG(MODULE_CPUINFO)
	&cpuinfo_module,
#endif
#if CONFIG(MODULE_PCI)
	&pci_module,
#endif
#if CONFIG(MODULE_NVRAM)
	&nvram_module,
#endif
#if CONFIG(MODULE_RAMDUMP)
	&ramdump_module,
#endif
};

struct coreinfo_module *firmware_modules[] = {
#if CONFIG(MODULE_COREBOOT)
	&coreboot_module,
#endif
#if CONFIG(MODULE_MULTIBOOT)
	&multiboot_module,
#endif
#if CONFIG(MODULE_BOOTLOG)
	&bootlog_module,
#endif
#if CONFIG(MODULE_CBFS)
	&cbfs_module,
#endif
#if CONFIG(MODULE_TIMESTAMPS)
	&timestamps_module,
#endif
};

struct coreinfo_cat {
	char name[15];
	int cur;
	int count;
	struct coreinfo_module **modules;
} categories[] = {
	{
		.name = "System",
		.modules = system_modules,
		.count = ARRAY_SIZE(system_modules),
	},
	{
		.name = "Firmware",
		.modules = firmware_modules,
		.count = ARRAY_SIZE(firmware_modules),
	}
};

static WINDOW *modwin, *menuwin;
static int curwin;

void print_module_title(WINDOW *win, const char *title)
{
	int i;

	wattrset(win, COLOR_PAIR(2));
	mvwprintw(win, 0, 1, title);

	wmove(win, 1, 1);
	for (i = 0; i < 78; i++)
		waddch(win, ACS_HLINE);
}

static void print_submenu(struct coreinfo_cat *cat)
{
	int i, j;
	char menu[80];
	char *ptr = menu;

	wmove(menuwin, 0, 0);

	for (j = 0; j < SCREEN_X; j++)
		waddch(menuwin, ' ');

	if (!cat->count)
		return;

	for (i = 0; i < cat->count; i++)
		ptr += sprintf(ptr, "[%c: %s] ", 'A' + i,
			       cat->modules[i]->name);

	mvwprintw(menuwin, 0, 0, menu);
}

#if CONFIG(SHOW_DATE_TIME)
static void print_time_and_date(void)
{
	struct tm tm;

	while (nvram_updating())
		mdelay(10);

	rtc_read_clock(&tm);

	mvwprintw(menuwin, 1, 57, "%02d/%02d/%04d - %02d:%02d:%02d",
		  tm.tm_mon + 1, tm.tm_mday, 1900 + tm.tm_year, tm.tm_hour,
		  tm.tm_min, tm.tm_sec);
}
#endif

static void print_menu(void)
{
	int j;
	char menu[80];
	char *ptr = menu;

	wmove(menuwin, 1, 0);
	for (j = 0; j < SCREEN_X; j++)
		waddch(menuwin, ' ');

	for (size_t i = 0; i < ARRAY_SIZE(categories); i++) {
		if (categories[i].count == 0)
			continue;

		ptr += sprintf(ptr, "F%zu: %s ", i + 1, categories[i].name);
	}

	mvwprintw(menuwin, 1, 0, menu);

#if CONFIG(SHOW_DATE_TIME)
	print_time_and_date();
#endif
}

static void center(int row, const char *str)
{
	int j, len = strlen(str);

	wmove(stdscr, row, 0);
	for (j = 0; j < SCREEN_X; j++)
		waddch(stdscr, ' ');

	mvprintw(row, (SCREEN_X - len) / 2, str);
}

/* FIXME: Currently unused. */
#if 0
static void header(int row, const char *str)
{
	char buf[SCREEN_X];
	char *ptr = buf;
	int i;
	int len = strlen(str) + 4;

	for (i = 0; i < (SCREEN_X - len) / 2; i++)
		ptr += sprintf(ptr, "=");

	ptr += sprintf(ptr, "[ %s ]", str);

	for (i = ((SCREEN_X - len) / 2) + len; i < SCREEN_X; i++)
		ptr += sprintf(ptr, "=");

	mvprintw(row, 0, buf);
}
#endif

static void redraw_module(struct coreinfo_cat *cat)
{
	if (cat->count == 0)
		return;

	wclear(modwin);
	cat->modules[cat->cur]->redraw(modwin);
	wrefresh(modwin);
}

static void handle_category_key(struct coreinfo_cat *cat, int key)
{
	if ((key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z')) {
		int index;
		if (key >= 'A' && key <= 'Z') {
			index = key - 'A';
		} else {
			index = key - 'a';
		}
		if (index < cat->count) {
			cat->cur = index;
			redraw_module(cat);
			return;
		}
	}

	if (cat->count && cat->modules[cat->cur]->handle) {
		if (cat->modules[cat->cur]->handle(key))
			redraw_module(cat);
	}
}

static void print_no_modules_selected(void)
{
	int height = getmaxy(stdscr);

	for (size_t i = 0; i < ARRAY_SIZE(categories); i++)
		if (categories[i].count > 0)
			return;

	color_set(2, NULL); // White on black
	center(height / 2, "No modules selected");
}

static int first_nonempty_category(void)
{
	for (size_t i = 0; i < ARRAY_SIZE(categories); i++)
		if (categories[i].count > 0)
			return i;
	return 0;
}

static void loop(void)
{
	int key;

	center(0, CONFIG_PAYLOAD_INFO_NAME " " CONFIG_PAYLOAD_INFO_VERSION);
	print_no_modules_selected();
	refresh();

	curwin = first_nonempty_category();
	print_menu();
	print_submenu(&categories[curwin]);
	redraw_module(&categories[curwin]);

	halfdelay(10);

	while (1) {
		int ch = -1;

#if CONFIG(SHOW_DATE_TIME)
		print_time_and_date();
		wrefresh(menuwin);
#endif

		key = getch();

		if (key == ERR)
			continue;

		if (key >= KEY_F(1) && key <= KEY_F(9))
			ch = key - KEY_F(1);
		if (key >= '1' && key <= '9')
			ch = key - '1';

		if (ch >= 0 && (unsigned int)ch <= ARRAY_SIZE(categories)) {
			if (ch == ARRAY_SIZE(categories))
				continue;
			if (categories[ch].count == 0)
				continue;

			curwin = ch;
			print_submenu(&categories[curwin]);
			redraw_module(&categories[curwin]);
			continue;
		}

		if (key == KEY_ESC)
			return;

		handle_category_key(&categories[curwin], key);
	}
}

int main(int argc, char **argv)
{
	(void)argc;
	(void)argv;

	int j;

	if (CONFIG(LP_USB))
		usb_initialize();

	initscr();

	start_color();
	init_pair(1, COLOR_WHITE, COLOR_GREEN);
	init_pair(2, COLOR_WHITE, COLOR_BLACK);
	init_pair(3, COLOR_BLACK, COLOR_WHITE);

	modwin = newwin(SCREEN_Y - 3, SCREEN_X, 1, 0);
	menuwin = newwin(2, SCREEN_X, SCREEN_Y - 2, 0);

	wattrset(stdscr, COLOR_PAIR(1) | A_BOLD);
	wattrset(modwin, COLOR_PAIR(2));
	wattrset(menuwin, COLOR_PAIR(1) | A_BOLD);

	werase(modwin);

	for (size_t i = 0; i < ARRAY_SIZE(categories); i++) {
		for (j = 0; j < categories[i].count; j++)
			categories[i].modules[j]->init();
	}

	noecho(); /* don't let curses echo keyboard chars */
	keypad(stdscr, TRUE); /* allow KEY_F(n) keys to be seen */
	curs_set(0); /* Hide blinking cursor */

	loop();

	/* reboot */
	outb(0x6, 0xcf9);
	halt();
	return 0;
}

PAYLOAD_INFO(name, CONFIG_PAYLOAD_INFO_NAME);
PAYLOAD_INFO(listname, CONFIG_PAYLOAD_INFO_LISTNAME);
PAYLOAD_INFO(desc, CONFIG_PAYLOAD_INFO_DESC);
