// 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_config.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)) && (CONFIG_IS_ENABLED(CMD_EFICONFIG))
/**
 * 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)) && (CONFIG_IS_ENABLED(CMD_EFICONFIG))
	if (i < MAX_COUNT - 1) {
		efi_status_t efi_ret;

		/*
		 * UEFI specification requires booting from removal media using
		 * a architecture-specific default image name such as BOOTAA64.EFI.
		 */
		efi_ret = eficonfig_generate_media_device_boot_option();
		if (efi_ret != EFI_SUCCESS && efi_ret != EFI_NOT_FOUND)
			goto cleanup;

		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 CFG_POSTBOOTMENU
	run_command(CFG_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"
);
