/*
 *
 * Copyright (C) 2012 secunet Security Networks AG
 *
 * 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 <coreboot_tables.h>
#include <libpayload.h>

#include <curses.h>
#include <form.h>
#include <menu.h>

#ifndef HOSTED
#define HOSTED 0
#endif

static int min(int x, int y)
{
	if (x < y)
		return x;
	return y;
}

static int max(int x, int y)
{
	if (x > y)
		return x;
	return y;
}

void render_form(FORM *form)
{
	int y, x, line;
	WINDOW *w = form_win(form);
	WINDOW *inner_w = form_sub(form);
	int numlines = getmaxy(w) - 2;
	getyx(inner_w, y, x);
	line = y - (y % numlines);
	WINDOW *der = derwin(w, getmaxy(w) - 2, getmaxx(w) - 2, 1, 1);
	wclear(der);
	wrefresh(der);
	delwin(der);
	copywin(inner_w, w, line, 0, 1, 1,
		min(numlines, getmaxy(inner_w) - line), 68, 0);
	wmove(w, y + 1 - line, x + 1);
	wrefresh(w);
}

/* determine number of options, and maximum option name length */
static int count_cmos_options(struct cb_cmos_entries *option, int *numopts,
		int *maxlength)
{
	int n_opts = 0;
	int max_l = 0;

	while (option) {
		if ((option->config != 'r') &&
		    (strcmp("check_sum", (char *)option->name) != 0)) {
			max_l = max(max_l, strlen((char *)option->name));
			n_opts++;
		}

		option = next_cmos_entry(option);
	}

	if (n_opts == 0) {
		printf("NO CMOS OPTIONS FOUND. EXITING!!!");
		return -1;
	}

	*numopts = n_opts;
	*maxlength = max_l;

	return 0;

}

/* walk over options, fetch details */
static void cmos_walk_options(struct cb_cmos_option_table *opttbl,
		FIELD **fields, int numopts, int maxlength)
{
	struct cb_cmos_entries *option = first_cmos_entry(opttbl);
	int i;

	for (i = 0; i < numopts; i++) {
		while ((option->config == 'r') ||
		       (strcmp("check_sum", (char *)option->name) == 0)) {
			option = next_cmos_entry(option);
		}
		fields[2 * i] =
		    new_field(1, strlen((char *)option->name), i * 2, 1, 0, 0);
		set_field_buffer(fields[2 * i], 0, (char *)option->name);
		field_opts_off(fields[2 * i], O_ACTIVE);

		fields[2 * i + 1] =
		    new_field(1, 40, i * 2, maxlength + 2, 0, 0);
		char *buf = NULL;
		int fail =
		    get_option_as_string(use_nvram, opttbl, &buf, (char *)option->name);
		switch (option->config) {
		case 'h': {
			set_field_type(fields[2 * i + 1], TYPE_INTEGER, 0, 0,
				       (1 << option->length) - 1);
			field_opts_on(fields[2 * i + 1], O_BLANK);
			break;
		}
		case 's': {
			set_max_field(fields[2 * i + 1], option->length / 8);
			field_opts_off(fields[2 * i + 1], O_STATIC);
			break;
		}
		case 'e': {
			int numvals = 0;
			struct cb_cmos_enums *cmos_enum =
			    first_cmos_enum_of_id(opttbl, option->config_id);

			/* if invalid data in CMOS, set buf to first enum */
			if (fail && cmos_enum) {
				buf = (char *)cmos_enum->text;
			}

			while (cmos_enum) {
				numvals++;
				cmos_enum = next_cmos_enum_of_id(
				    cmos_enum, option->config_id);
			}

			char **values = malloc(sizeof(char *) * (numvals + 1));
			int cnt = 0;

			cmos_enum =
			    first_cmos_enum_of_id(opttbl, option->config_id);
			while (cmos_enum) {
				values[cnt] = (char *)cmos_enum->text;
				cnt++;
				cmos_enum = next_cmos_enum_of_id(
				    cmos_enum, option->config_id);
			}
			values[cnt] = NULL;
			field_opts_off(fields[2 * i + 1], O_EDIT);
			set_field_type(fields[2 * i + 1], TYPE_ENUM, values, 1,
				       1);
			free(values); // copied by set_field_type
			break;
		}
		default:
			break;
		}
		if (buf)
			set_field_buffer(fields[2 * i + 1], 0, buf);
#if HOSTED
		// underline is non-trivial on VGA text
		set_field_back(fields[2 * i + 1], A_UNDERLINE);
#endif
		field_opts_off(fields[2 * i + 1],
			       O_BLANK | O_AUTOSKIP | O_NULLOK);

		option = next_cmos_entry(option);
	}

	fields[2 * numopts] = NULL;
}

int main(void)
{
	int ch, done;
	int i;

	if (CONFIG(LP_USB))
		usb_initialize();

	/* coreboot data structures */
	lib_get_sysinfo();

	struct cb_cmos_option_table *opttbl = get_system_option_table();

	if (opttbl == NULL) {
		printf("Could not find coreboot option table.\n");
		halt();
	}

	/* prep CMOS layout into libcurses data structures */

	struct cb_cmos_entries *option = first_cmos_entry(opttbl);
	int numopts = 0;
	int maxlength = 0;

	count_cmos_options(option, &numopts, &maxlength);

	FIELD **fields = malloc(sizeof(FIELD *) * (2 * numopts + 1));

	cmos_walk_options(opttbl, fields, numopts, maxlength);

	/* display initialization */
	initscr();
	keypad(stdscr, TRUE);
	cbreak();
	noecho();

	if (start_color()) {
		assume_default_colors(COLOR_BLUE, COLOR_CYAN);
	}
	leaveok(stdscr, TRUE);
	curs_set(1);

	erase();
	box(stdscr, 0, 0);
	mvaddstr(0, 2, "coreboot configuration utility");
	refresh();

	FORM *form = new_form(fields);
	int numlines = min(numopts * 2, 16);
	WINDOW *w = newwin(numlines + 2, 70, 2, 1);
	WINDOW *inner_w = newpad(numopts * 2, 68);
	box(w, 0, 0);
	mvwaddstr(w, 0, 2, "Press F1 when done");
	set_form_win(form, w);
	set_form_sub(form, inner_w);
	post_form(form);

	done = 0;
	while (!done) {
		render_form(form);
		ch = getch();
		if (ch == ERR)
			continue;
		switch (ch) {
		case KEY_DOWN:
			form_driver(form, REQ_NEXT_FIELD);
			break;
		case KEY_UP:
			form_driver(form, REQ_PREV_FIELD);
			break;
		case KEY_LEFT:
			if (field_type(current_field(form)) == TYPE_ENUM) {
				form_driver(form, REQ_PREV_CHOICE);
			} else {
				form_driver(form, REQ_LEFT_CHAR);
			}
			break;
		case KEY_RIGHT:
			if (field_type(current_field(form)) == TYPE_ENUM) {
				form_driver(form, REQ_NEXT_CHOICE);
			} else {
				form_driver(form, REQ_RIGHT_CHAR);
			}
			break;
		case KEY_BACKSPACE:
		case '\b':
			form_driver(form, REQ_DEL_PREV);
			break;
		case KEY_DC:
			form_driver(form, REQ_DEL_CHAR);
			break;
		case KEY_F(1):
			done = 1;
			break;
		default:
			form_driver(form, ch);
			break;
		}
	}

	endwin();

	for (i = 0; i < numopts; i++) {
		char *name = field_buffer(fields[2 * i], 0);
		char *value = field_buffer(fields[2 * i + 1], 0);
		char *ptr;
		for (ptr = value + strlen(value) - 1;
		     ptr >= value && *ptr == ' '; ptr--)
			;
		ptr[1] = '\0';
		set_option_from_string(use_nvram, opttbl, value, name);
	}

	unpost_form(form);
	free_form(form);

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