/*
 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * 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; either version 2 of the
 * License, or any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <curses.h>
#include <ipxe/console.h>
#include <ipxe/settings.h>
#include <ipxe/editbox.h>
#include <ipxe/keys.h>
#include <ipxe/ansicol.h>
#include <ipxe/jumpscroll.h>
#include <ipxe/message.h>
#include <ipxe/settings_ui.h>
#include <config/branding.h>

/** @file
 *
 * Option configuration console
 *
 */

/* Screen layout */
#define TITLE_ROW		1U
#define SETTINGS_LIST_ROW	3U
#define SETTINGS_LIST_COL	1U
#define SETTINGS_LIST_ROWS	( LINES - 6U - SETTINGS_LIST_ROW )
#define INFO_ROW		( LINES - 5U )
#define ALERT_ROW		( LINES - 2U )
#define INSTRUCTION_ROW		( LINES - 2U )
#define INSTRUCTION_PAD "     "

/** Layout of text within a setting row */
#define SETTING_ROW_TEXT( cols ) struct {				\
	char start[0];							\
	char pad1[1];							\
	union {								\
		struct {						\
			char name[ cols - 1 - 1 - 1 - 1 - 1 ];		\
			char pad2[1];					\
		} __attribute__ (( packed )) settings;			\
		struct {						\
			char name[15];					\
			char pad2[1];					\
			char value[ cols - 1 - 15 - 1 - 1 - 1 - 1 ];	\
		} __attribute__ (( packed )) setting;			\
	} u;								\
	char pad3[1];							\
	char nul;							\
} __attribute__ (( packed ))

/** A settings user interface row */
struct settings_ui_row {
	/** Target configuration settings block
	 *
	 * Valid only for rows that lead to new settings blocks.
	 */
	struct settings *settings;
	/** Configuration setting origin
	 *
	 * Valid only for rows that represent individual settings.
	 */
	struct settings *origin;
	/** Configuration setting
	 *
	 * Valid only for rows that represent individual settings.
	 */
	struct setting setting;
	/** Screen row */
	unsigned int row;
	/** Edit box widget used for editing setting */
	struct edit_box editbox;
	/** Editing in progress flag */
	int editing;
	/** Dynamically allocated buffer for setting's value */
	char *buf;
};

/** A settings user interface */
struct settings_ui {
	/** Settings block */
	struct settings *settings;
	/** Jump scroller */
	struct jump_scroller scroll;
	/** Current row */
	struct settings_ui_row row;
	/** Widget set used for editing setting */
	struct widgets widgets;
};

/**
 * Select a setting
 *
 * @v ui		Settings user interface
 * @v index		Index of setting row
 * @ret count		Number of setting rows
 */
static unsigned int select_setting_row ( struct settings_ui *ui,
					 unsigned int index ) {
	SETTING_ROW_TEXT ( COLS ) *text;
	struct settings *settings;
	struct setting *setting;
	struct setting *previous = NULL;
	unsigned int count = 0;

	/* Free any previous setting value */
	free ( ui->row.buf );
	ui->row.buf = NULL;

	/* Initialise structure */
	memset ( &ui->row, 0, sizeof ( ui->row ) );
	ui->row.row = ( SETTINGS_LIST_ROW + index - ui->scroll.first );

	/* Include parent settings block, if applicable */
	if ( ui->settings->parent && ( count++ == index ) )
		ui->row.settings = ui->settings->parent;

	/* Include any child settings blocks, if applicable */
	list_for_each_entry ( settings, &ui->settings->children, siblings ) {
		if ( count++ == index )
			ui->row.settings = settings;
	}

	/* Include any applicable settings */
	for_each_table_entry ( setting, SETTINGS ) {

		/* Skip inapplicable settings */
		if ( ! setting_applies ( ui->settings, setting ) )
			continue;

		/* Skip duplicate settings */
		if ( previous && ( setting_cmp ( setting, previous ) == 0 ) )
			continue;
		previous = setting;

		/* Read current setting value and origin */
		if ( count++ == index ) {
			fetchf_setting_copy ( ui->settings, setting,
					      &ui->row.origin,
					      &ui->row.setting, &ui->row.buf );
		}
	}

	/* Initialise edit box */
	memset ( &ui->row.editbox, 0, sizeof ( ui->row.editbox ) );
	init_editbox ( &ui->row.editbox, ui->row.row,
		       ( SETTINGS_LIST_COL +
			 offsetof ( typeof ( *text ), u.setting.value ) ),
		       sizeof ( text->u.setting.value ), 0, &ui->row.buf );

	return count;
}

/**
 * Copy string without NUL termination
 *
 * @v dest		Destination
 * @v src		Source
 * @v len		Maximum length of destination
 * @ret len		Length of (unterminated) string
 */
static size_t string_copy ( char *dest, const char *src, size_t len ) {
	size_t src_len;

	src_len = strlen ( src );
	if ( len > src_len )
		len = src_len;
	memcpy ( dest, src, len );
	return len;
}

/**
 * Draw setting row
 *
 * @v ui		Settings UI
 */
static void draw_setting_row ( struct settings_ui *ui ) {
	SETTING_ROW_TEXT ( COLS ) text;
	unsigned int curs_offset;
	const char *value;

	/* Fill row with spaces */
	memset ( &text, ' ', sizeof ( text ) );
	text.nul = '\0';

	/* Construct row content */
	if ( ui->row.settings ) {

		/* Construct space-padded name */
		value = ( ( ui->row.settings == ui->settings->parent ) ?
			  ".." : ui->row.settings->name );
		curs_offset = string_copy ( text.u.settings.name, value,
					    sizeof ( text.u.settings.name ) );
		text.u.settings.name[curs_offset] = '/';
		curs_offset += offsetof ( typeof ( text ), u.settings );

	} else {

		/* Construct dot-padded name */
		memset ( text.u.setting.name, '.',
			 sizeof ( text.u.setting.name ) );
		string_copy ( text.u.setting.name, ui->row.setting.name,
			      sizeof ( text.u.setting.name ) );

		/* Construct space-padded value */
		value = ui->row.buf;
		if ( ! ( value && value[0] ) )
			value = "<not specified>";
		curs_offset = string_copy ( text.u.setting.value, value,
					    sizeof ( text.u.setting.value ) );
		curs_offset += offsetof ( typeof ( text ), u.setting.value );
	}

	/* Print row */
	if ( ( ui->row.origin == ui->settings ) || ( ui->row.settings != NULL ))
		attron ( A_BOLD );
	mvprintw ( ui->row.row, SETTINGS_LIST_COL, "%s", text.start );
	attroff ( A_BOLD );
	move ( ui->row.row, ( SETTINGS_LIST_COL + curs_offset ) );
}

/**
 * Edit setting ui
 *
 * @v ui		Settings UI
 * @v key		Key pressed by user
 * @ret key		Key returned to application, or zero
 */
static int edit_setting ( struct settings_ui *ui, int key ) {
	assert ( ui->row.setting.name != NULL );
	ui->row.editing = 1;
	return edit_widget ( &ui->row.editbox.widget, key );
}

/**
 * Save setting ui value back to configuration settings
 *
 * @v ui		Settings UI
 */
static int save_setting ( struct settings_ui *ui ) {
	assert ( ui->row.setting.name != NULL );
	return storef_setting ( ui->settings, &ui->row.setting, ui->row.buf );
}

/**
 * Draw title row
 *
 * @v ui		Settings UI
 */
static void draw_title_row ( struct settings_ui *ui ) {
	const char *name;

	clearmsg ( TITLE_ROW );
	name = settings_name ( ui->settings );
	attron ( A_BOLD );
	msg ( TITLE_ROW, PRODUCT_SHORT_NAME " configuration settings%s%s",
	      ( name[0] ? " - " : "" ), name );
	attroff ( A_BOLD );
}

/**
 * Draw information row
 *
 * @v ui		Settings UI
 */
static void draw_info_row ( struct settings_ui *ui ) {
	char buf[32];

	/* Draw nothing unless this row represents a setting */
	clearmsg ( INFO_ROW );
	clearmsg ( INFO_ROW + 1 );
	if ( ! ui->row.setting.name )
		return;

	/* Determine a suitable setting name */
	setting_name ( ( ui->row.origin ?
			 ui->row.origin : ui->settings ),
		       &ui->row.setting, buf, sizeof ( buf ) );

	/* Draw row */
	attron ( A_BOLD );
	msg ( INFO_ROW, "%s - %s", buf, ui->row.setting.description );
	attroff ( A_BOLD );
	color_set ( CPAIR_URL, NULL );
	msg ( ( INFO_ROW + 1 ), PRODUCT_SETTING_URI, ui->row.setting.name );
	color_set ( CPAIR_NORMAL, NULL );
}

/**
 * Draw instruction row
 *
 * @v ui		Settings UI
 */
static void draw_instruction_row ( struct settings_ui *ui ) {

	clearmsg ( INSTRUCTION_ROW );
	if ( ui->row.editing ) {
		msg ( INSTRUCTION_ROW,
		      "Enter - accept changes" INSTRUCTION_PAD
		      "Ctrl-C - discard changes" );
	} else {
		msg ( INSTRUCTION_ROW,
		      "%sCtrl-X - exit configuration utility",
		      ( ( ui->row.origin == ui->settings ) ?
			"Ctrl-D - delete setting" INSTRUCTION_PAD : "" ) );
	}
}

/**
 * Draw the current block of setting rows
 *
 * @v ui		Settings UI
 */
static void draw_setting_rows ( struct settings_ui *ui ) {
	unsigned int i;

	/* Draw ellipses before and/or after the list as necessary */
	color_set ( CPAIR_SEPARATOR, NULL );
	mvaddstr ( ( SETTINGS_LIST_ROW - 1 ), ( SETTINGS_LIST_COL + 1 ),
		   jump_scroll_is_first ( &ui->scroll ) ? "   " : "..." );
	mvaddstr ( ( SETTINGS_LIST_ROW + SETTINGS_LIST_ROWS ),
		   ( SETTINGS_LIST_COL + 1 ),
		   jump_scroll_is_last ( &ui->scroll ) ? "   " : "..." );
	color_set ( CPAIR_NORMAL, NULL );

	/* Draw visible settings. */
	for ( i = 0 ; i < SETTINGS_LIST_ROWS ; i++ ) {
		if ( ( ui->scroll.first + i ) < ui->scroll.count ) {
			select_setting_row ( ui, ( ui->scroll.first + i ) );
			draw_setting_row ( ui );
		} else {
			clearmsg ( SETTINGS_LIST_ROW + i );
		}
	}
}

/**
 * Select settings block
 *
 * @v ui		Settings UI
 * @v settings		Settings block
 */
static void select_settings ( struct settings_ui *ui,
			      struct settings *settings ) {

	ui->settings = settings_target ( settings );
	ui->scroll.count = select_setting_row ( ui, 0 );
	ui->scroll.rows = SETTINGS_LIST_ROWS;
	ui->scroll.current = 0;
	ui->scroll.first = 0;
	draw_title_row ( ui );
	draw_setting_rows ( ui );
	select_setting_row ( ui, 0 );
}

static int main_loop ( struct settings *settings ) {
	struct settings_ui ui;
	unsigned int previous;
	unsigned int move;
	int redraw = 1;
	int key;
	int rc;

	/* Print initial screen content */
	color_set ( CPAIR_NORMAL, NULL );
	memset ( &ui, 0, sizeof ( ui ) );
	init_widgets ( &ui.widgets );
	select_settings ( &ui, settings );

	while ( 1 ) {

		/* Redraw rows if necessary */
		if ( redraw ) {
			draw_info_row ( &ui );
			draw_instruction_row ( &ui );
			color_set ( ( ui.row.editing ?
				      CPAIR_EDIT : CPAIR_SELECT ), NULL );
			draw_setting_row ( &ui );
			color_set ( CPAIR_NORMAL, NULL );
			curs_set ( ui.row.editing );
			redraw = 0;
		}

		/* Edit setting, if we are currently editing */
		if ( ui.row.editing ) {

			/* Sanity check */
			assert ( ui.row.setting.name != NULL );

			/* Redraw edit box */
			draw_widget ( &ui.row.editbox.widget );

			/* Process keypress */
			key = edit_setting ( &ui, getkey ( 0 ) );
			switch ( key ) {
			case CR:
			case LF:
				if ( ( rc = save_setting ( &ui ) ) != 0 ) {
					alert ( ALERT_ROW, " %s ",
						strerror ( rc ) );
				}
				/* Fall through */
			case CTRL_C:
				select_setting_row ( &ui, ui.scroll.current );
				redraw = 1;
				break;
			default:
				/* Do nothing */
				break;
			}

			continue;
		}

		/* Otherwise, navigate through settings */
		key = getkey ( 0 );
		move = jump_scroll_key ( &ui.scroll, key );
		if ( move ) {
			previous = ui.scroll.current;
			jump_scroll_move ( &ui.scroll, move );
			if ( ui.scroll.current != previous ) {
				draw_setting_row ( &ui );
				redraw = 1;
				if ( jump_scroll ( &ui.scroll ) )
					draw_setting_rows ( &ui );
				select_setting_row ( &ui, ui.scroll.current );
			}
			continue;
		}

		/* Handle non-navigation keys */
		switch ( key ) {
		case CTRL_D:
			if ( ! ui.row.setting.name )
				break;
			if ( ( rc = delete_setting ( ui.settings,
						     &ui.row.setting ) ) != 0 ){
				alert ( ALERT_ROW, " %s ", strerror ( rc ) );
			}
			select_setting_row ( &ui, ui.scroll.current );
			redraw = 1;
			break;
		case CTRL_X:
			select_setting_row ( &ui, -1U );
			return 0;
		case CR:
		case LF:
			if ( ui.row.settings ) {
				select_settings ( &ui, ui.row.settings );
				redraw = 1;
			}
			/* Fall through */
		default:
			if ( ui.row.setting.name ) {
				edit_setting ( &ui, key );
				redraw = 1;
			}
			break;
		}
	}
}

int settings_ui ( struct settings *settings ) {
	int rc;

	initscr();
	start_color();
	color_set ( CPAIR_NORMAL, NULL );
	curs_set ( 0 );
	erase();
	
	rc = main_loop ( settings );

	endwin();

	return rc;
}
