// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2011-2013 Pali Rohár <pali@kernel.org>
 */

#include <charset.h>
#include <common.h>
#include <command.h>
#include <ansi.h>
#include <efi_loader.h>
#include <efi_variable.h>
#include <env.h>
#include <log.h>
#include <menu.h>
#include <watchdog.h>
#include <malloc.h>
#include <linux/delay.h>
#include <linux/string.h>

/* maximum bootmenu entries */
#define MAX_COUNT	99

/* maximal size of bootmenu env
 *  9 = strlen("bootmenu_")
 *  2 = strlen(MAX_COUNT)
 *  1 = NULL term
 */
#define MAX_ENV_SIZE	(9 + 2 + 1)

enum bootmenu_ret {
	BOOTMENU_RET_SUCCESS = 0,
	BOOTMENU_RET_FAIL,
	BOOTMENU_RET_QUIT,
	BOOTMENU_RET_UPDATED,
};

enum boot_type {
	BOOTMENU_TYPE_NONE = 0,
	BOOTMENU_TYPE_BOOTMENU,
	BOOTMENU_TYPE_UEFI_BOOT_OPTION,
};

struct bootmenu_entry {
	unsigned short int num;		/* unique number 0 .. MAX_COUNT */
	char key[3];			/* key identifier of number */
	char *title;			/* title of entry */
	char *command;			/* hush command of entry */
	enum boot_type type;		/* boot type of entry */
	u16 bootorder;			/* order for each boot type */
	struct bootmenu_data *menu;	/* this bootmenu */
	struct bootmenu_entry *next;	/* next menu entry (num+1) */
};

static char *bootmenu_getoption(unsigned short int n)
{
	char name[MAX_ENV_SIZE];

	if (n > MAX_COUNT)
		return NULL;

	sprintf(name, "bootmenu_%d", n);
	return env_get(name);
}

static void bootmenu_print_entry(void *data)
{
	struct bootmenu_entry *entry = data;
	int reverse = (entry->menu->active == entry->num);

	/*
	 * Move cursor to line where the entry will be drown (entry->num)
	 * First 3 lines contain bootmenu header + 1 empty line
	 */
	printf(ANSI_CURSOR_POSITION, entry->num + 4, 7);

	if (reverse)
		puts(ANSI_COLOR_REVERSE);

	printf("%s", entry->title);

	if (reverse)
		puts(ANSI_COLOR_RESET);
}

static char *bootmenu_choice_entry(void *data)
{
	struct bootmenu_data *menu = data;
	struct bootmenu_entry *iter;
	enum bootmenu_key key = KEY_NONE;
	int esc = 0;
	int i;

	while (1) {
		if (menu->delay >= 0) {
			/* Autoboot was not stopped */
			bootmenu_autoboot_loop(menu, &key, &esc);
		} else {
			/* Some key was pressed, so autoboot was stopped */
			bootmenu_loop(menu, &key, &esc);
		}

		switch (key) {
		case KEY_UP:
			if (menu->active > 0)
				--menu->active;
			/* no menu key selected, regenerate menu */
			return NULL;
		case KEY_DOWN:
			if (menu->active < menu->count - 1)
				++menu->active;
			/* no menu key selected, regenerate menu */
			return NULL;
		case KEY_SELECT:
			iter = menu->first;
			for (i = 0; i < menu->active; ++i)
				iter = iter->next;
			return iter->key;
		case KEY_QUIT:
			/* Quit by choosing the last entry - U-Boot console */
			iter = menu->first;
			while (iter->next)
				iter = iter->next;
			return iter->key;
		default:
			break;
		}
	}

	/* never happens */
	debug("bootmenu: this should not happen");
	return NULL;
}

static void bootmenu_destroy(struct bootmenu_data *menu)
{
	struct bootmenu_entry *iter = menu->first;
	struct bootmenu_entry *next;

	while (iter) {
		next = iter->next;
		free(iter->title);
		free(iter->command);
		free(iter);
		iter = next;
	}
	free(menu);
}

/**
 * prepare_bootmenu_entry() - generate the bootmenu_xx entries
 *
 * This function read the "bootmenu_x" U-Boot environment variable
 * and generate the bootmenu entries.
 *
 * @menu:	pointer to the bootmenu structure
 * @current:	pointer to the last bootmenu entry list
 * @index:	pointer to the index of the last bootmenu entry,
 *		the number of bootmenu entry is added by this function
 * Return:	1 on success, negative value on error
 */
static int prepare_bootmenu_entry(struct bootmenu_data *menu,
				  struct bootmenu_entry **current,
				  unsigned short int *index)
{
	char *sep;
	const char *option;
	unsigned short int i = *index;
	struct bootmenu_entry *entry = NULL;
	struct bootmenu_entry *iter = *current;

	while ((option = bootmenu_getoption(i))) {

		/* bootmenu_[num] format is "[title]=[commands]" */
		sep = strchr(option, '=');
		if (!sep) {
			printf("Invalid bootmenu entry: %s\n", option);
			break;
		}

		entry = malloc(sizeof(struct bootmenu_entry));
		if (!entry)
			return -ENOMEM;

		entry->title = strndup(option, sep - option);
		if (!entry->title) {
			free(entry);
			return -ENOMEM;
		}

		entry->command = strdup(sep + 1);
		if (!entry->command) {
			free(entry->title);
			free(entry);
			return -ENOMEM;
		}

		sprintf(entry->key, "%d", i);

		entry->num = i;
		entry->menu = menu;
		entry->type = BOOTMENU_TYPE_BOOTMENU;
		entry->bootorder = i;
		entry->next = NULL;

		if (!iter)
			menu->first = entry;
		else
			iter->next = entry;

		iter = entry;
		++i;

		if (i == MAX_COUNT - 1)
			break;
	}

	*index = i;
	*current = iter;

	return 1;
}

#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR))
/**
 * prepare_uefi_bootorder_entry() - generate the uefi bootmenu entries
 *
 * This function read the "BootOrder" UEFI variable
 * and generate the bootmenu entries in the order of "BootOrder".
 *
 * @menu:	pointer to the bootmenu structure
 * @current:	pointer to the last bootmenu entry list
 * @index:	pointer to the index of the last bootmenu entry,
 *		the number of uefi entry is added by this function
 * Return:	1 on success, negative value on error
 */
static int prepare_uefi_bootorder_entry(struct bootmenu_data *menu,
					struct bootmenu_entry **current,
					unsigned short int *index)
{
	u16 *bootorder;
	efi_status_t ret;
	unsigned short j;
	efi_uintn_t num, size;
	void *load_option;
	struct efi_load_option lo;
	u16 varname[] = u"Boot####";
	unsigned short int i = *index;
	struct bootmenu_entry *entry = NULL;
	struct bootmenu_entry *iter = *current;

	bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
	if (!bootorder)
		return -ENOENT;

	num = size / sizeof(u16);
	for (j = 0; j < num; j++) {
		entry = malloc(sizeof(struct bootmenu_entry));
		if (!entry)
			return -ENOMEM;

		efi_create_indexed_name(varname, sizeof(varname),
					"Boot", bootorder[j]);
		load_option = efi_get_var(varname, &efi_global_variable_guid, &size);
		if (!load_option)
			continue;

		ret = efi_deserialize_load_option(&lo, load_option, &size);
		if (ret != EFI_SUCCESS) {
			log_warning("Invalid load option for %ls\n", varname);
			free(load_option);
			free(entry);
			continue;
		}

		if (lo.attributes & LOAD_OPTION_ACTIVE) {
			char *buf;

			buf = calloc(1, utf16_utf8_strlen(lo.label) + 1);
			if (!buf) {
				free(load_option);
				free(entry);
				free(bootorder);
				return -ENOMEM;
			}
			entry->title = buf;
			utf16_utf8_strncpy(&buf, lo.label, u16_strlen(lo.label));
			entry->command = strdup("bootefi bootmgr");
			sprintf(entry->key, "%d", i);
			entry->num = i;
			entry->menu = menu;
			entry->type = BOOTMENU_TYPE_UEFI_BOOT_OPTION;
			entry->bootorder = bootorder[j];
			entry->next = NULL;

			if (!iter)
				menu->first = entry;
			else
				iter->next = entry;

			iter = entry;
			i++;
		}

		free(load_option);

		if (i == MAX_COUNT - 1)
			break;
	}

	free(bootorder);
	*index = i;
	*current = iter;

	return 1;
}
#endif

static struct bootmenu_data *bootmenu_create(int delay)
{
	int ret;
	unsigned short int i = 0;
	struct bootmenu_data *menu;
	struct bootmenu_entry *iter = NULL;
	struct bootmenu_entry *entry;
	char *default_str;

	menu = malloc(sizeof(struct bootmenu_data));
	if (!menu)
		return NULL;

	menu->delay = delay;
	menu->active = 0;
	menu->first = NULL;

	default_str = env_get("bootmenu_default");
	if (default_str)
		menu->active = (int)simple_strtol(default_str, NULL, 10);

	ret = prepare_bootmenu_entry(menu, &iter, &i);
	if (ret < 0)
		goto cleanup;

#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR))
	if (i < MAX_COUNT - 1) {
			ret = prepare_uefi_bootorder_entry(menu, &iter, &i);
			if (ret < 0 && ret != -ENOENT)
				goto cleanup;
	}
#endif

	/* Add U-Boot console entry at the end */
	if (i <= MAX_COUNT - 1) {
		entry = malloc(sizeof(struct bootmenu_entry));
		if (!entry)
			goto cleanup;

		/* Add Quit entry if entering U-Boot console is disabled */
		if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE))
			entry->title = strdup("U-Boot console");
		else
			entry->title = strdup("Quit");

		if (!entry->title) {
			free(entry);
			goto cleanup;
		}

		entry->command = strdup("");
		if (!entry->command) {
			free(entry->title);
			free(entry);
			goto cleanup;
		}

		sprintf(entry->key, "%d", i);

		entry->num = i;
		entry->menu = menu;
		entry->type = BOOTMENU_TYPE_NONE;
		entry->next = NULL;

		if (!iter)
			menu->first = entry;
		else
			iter->next = entry;

		iter = entry;
		++i;
	}

	menu->count = i;

	if ((menu->active >= menu->count)||(menu->active < 0)) { //ensure active menuitem is inside menu
		printf("active menuitem (%d) is outside menu (0..%d)\n",menu->active,menu->count-1);
		menu->active=0;
	}

	return menu;

cleanup:
	bootmenu_destroy(menu);
	return NULL;
}

static void menu_display_statusline(struct menu *m)
{
	struct bootmenu_entry *entry;
	struct bootmenu_data *menu;

	if (menu_default_choice(m, (void *)&entry) < 0)
		return;

	menu = entry->menu;

	printf(ANSI_CURSOR_POSITION, 1, 1);
	puts(ANSI_CLEAR_LINE);
	printf(ANSI_CURSOR_POSITION, 2, 3);
	puts("*** U-Boot Boot Menu ***");
	puts(ANSI_CLEAR_LINE_TO_END);
	printf(ANSI_CURSOR_POSITION, 3, 1);
	puts(ANSI_CLEAR_LINE);

	/* First 3 lines are bootmenu header + 2 empty lines between entries */
	printf(ANSI_CURSOR_POSITION, menu->count + 5, 1);
	puts(ANSI_CLEAR_LINE);
	printf(ANSI_CURSOR_POSITION, menu->count + 6, 3);
	puts("Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit");
	puts(ANSI_CLEAR_LINE_TO_END);
	printf(ANSI_CURSOR_POSITION, menu->count + 7, 1);
	puts(ANSI_CLEAR_LINE);
}

static void handle_uefi_bootnext(void)
{
	u16 bootnext;
	efi_status_t ret;
	efi_uintn_t size;

	/* Initialize EFI drivers */
	ret = efi_init_obj_list();
	if (ret != EFI_SUCCESS) {
		log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n",
			ret & ~EFI_ERROR_MASK);

		return;
	}

	/* If UEFI BootNext variable is set, boot the BootNext load option */
	size = sizeof(u16);
	ret = efi_get_variable_int(u"BootNext",
				   &efi_global_variable_guid,
				   NULL, &size, &bootnext, NULL);
	if (ret == EFI_SUCCESS)
		/* BootNext does exist here, try to boot */
		run_command("bootefi bootmgr", 0);
}

static enum bootmenu_ret bootmenu_show(int delay)
{
	int cmd_ret;
	int init = 0;
	void *choice = NULL;
	char *title = NULL;
	char *command = NULL;
	struct menu *menu;
	struct bootmenu_entry *iter;
	int ret = BOOTMENU_RET_SUCCESS;
	struct bootmenu_data *bootmenu;
	efi_status_t efi_ret = EFI_SUCCESS;
	char *option, *sep;

	if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR))
		handle_uefi_bootnext();

	/* If delay is 0 do not create menu, just run first entry */
	if (delay == 0) {
		option = bootmenu_getoption(0);
		if (!option) {
			puts("bootmenu option 0 was not found\n");
			return BOOTMENU_RET_FAIL;
		}
		sep = strchr(option, '=');
		if (!sep) {
			puts("bootmenu option 0 is invalid\n");
			return BOOTMENU_RET_FAIL;
		}
		cmd_ret = run_command(sep + 1, 0);
		return (cmd_ret == CMD_RET_SUCCESS ? BOOTMENU_RET_SUCCESS : BOOTMENU_RET_FAIL);
	}

	bootmenu = bootmenu_create(delay);
	if (!bootmenu)
		return BOOTMENU_RET_FAIL;

	menu = menu_create(NULL, bootmenu->delay, 1, menu_display_statusline,
			   bootmenu_print_entry, bootmenu_choice_entry,
			   bootmenu);
	if (!menu) {
		bootmenu_destroy(bootmenu);
		return BOOTMENU_RET_FAIL;
	}

	for (iter = bootmenu->first; iter; iter = iter->next) {
		if (menu_item_add(menu, iter->key, iter) != 1)
			goto cleanup;
	}

	/* Default menu entry is always first */
	menu_default_set(menu, "0");

	puts(ANSI_CURSOR_HIDE);
	puts(ANSI_CLEAR_CONSOLE);
	printf(ANSI_CURSOR_POSITION, 1, 1);

	init = 1;

	if (menu_get_choice(menu, &choice) == 1) {
		iter = choice;
		title = strdup(iter->title);
		command = strdup(iter->command);

		/* last entry is U-Boot console or Quit */
		if (iter->num == iter->menu->count - 1) {
			ret = BOOTMENU_RET_QUIT;
			goto cleanup;
		}
	} else {
		goto cleanup;
	}

	/*
	 * If the selected entry is UEFI BOOT####, set the BootNext variable.
	 * Then uefi bootmgr is invoked by the preset command in iter->command.
	 */
	if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
		if (iter->type == BOOTMENU_TYPE_UEFI_BOOT_OPTION) {
			/*
			 * UEFI specification requires BootNext variable needs non-volatile
			 * attribute, but this BootNext is only used inside of U-Boot and
			 * removed by efi bootmgr once BootNext is processed.
			 * So this BootNext can be volatile.
			 */
			efi_ret = efi_set_variable_int(u"BootNext", &efi_global_variable_guid,
						       EFI_VARIABLE_BOOTSERVICE_ACCESS |
						       EFI_VARIABLE_RUNTIME_ACCESS,
						       sizeof(u16), &iter->bootorder, false);
			if (efi_ret != EFI_SUCCESS)
				goto cleanup;
		}
	}

cleanup:
	menu_destroy(menu);
	bootmenu_destroy(bootmenu);

	if (init) {
		puts(ANSI_CURSOR_SHOW);
		puts(ANSI_CLEAR_CONSOLE);
		printf(ANSI_CURSOR_POSITION, 1, 1);
	}

	if (title && command) {
		debug("Starting entry '%s'\n", title);
		free(title);
		if (efi_ret == EFI_SUCCESS)
			cmd_ret = run_command(command, 0);
		free(command);
	}

#ifdef CONFIG_POSTBOOTMENU
	run_command(CONFIG_POSTBOOTMENU, 0);
#endif

	if (efi_ret != EFI_SUCCESS || cmd_ret != CMD_RET_SUCCESS)
		ret = BOOTMENU_RET_FAIL;

	return ret;
}

#ifdef CONFIG_AUTOBOOT_MENU_SHOW
int menu_show(int bootdelay)
{
	int ret;

	while (1) {
		ret = bootmenu_show(bootdelay);
		bootdelay = -1;
		if (ret == BOOTMENU_RET_UPDATED)
			continue;

		if (IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE)) {
			if (ret == BOOTMENU_RET_QUIT) {
				/* default boot process */
				if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR))
					run_command("bootefi bootmgr", 0);

				run_command("run bootcmd", 0);
			}
		} else {
			break;
		}
	}

	return -1; /* -1 - abort boot and run monitor code */
}
#endif

int do_bootmenu(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	char *delay_str = NULL;
	int delay = 10;

#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
	delay = CONFIG_BOOTDELAY;
#endif

	if (argc >= 2)
		delay_str = argv[1];

	if (!delay_str)
		delay_str = env_get("bootmenu_delay");

	if (delay_str)
		delay = (int)simple_strtol(delay_str, NULL, 10);

	bootmenu_show(delay);
	return 0;
}

U_BOOT_CMD(
	bootmenu, 2, 1, do_bootmenu,
	"ANSI terminal bootmenu",
	"[delay]\n"
	"    - show ANSI terminal bootmenu with autoboot delay"
);
