// 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 */
	u16 *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("%ls", 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)
{
	int len;
	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))) {
		u16 *buf;

		sep = strchr(option, '=');
		if (!sep) {
			printf("Invalid bootmenu entry: %s\n", option);
			break;
		}

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

		len = sep-option;
		buf = calloc(1, (len + 1) * sizeof(u16));
		entry->title = buf;
		if (!entry->title) {
			free(entry);
			return -ENOMEM;
		}
		utf8_utf16_strncpy(&buf, option, len);

		len = strlen(sep + 1);
		entry->command = malloc(len + 1);
		if (!entry->command) {
			free(entry->title);
			free(entry);
			return -ENOMEM;
		}
		memcpy(entry->command, sep + 1, len);
		entry->command[len] = 0;

		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;
}

/**
 * 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) {
			entry->title = u16_strdup(lo.label);
			if (!entry->title) {
				free(load_option);
				free(entry);
				free(bootorder);
				return -ENOMEM;
			}
			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;
}

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 (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) {
		if (i < MAX_COUNT - 1) {
			ret = prepare_uefi_bootorder_entry(menu, &iter, &i);
			if (ret < 0 && ret != -ENOENT)
				goto cleanup;
		}
	}

	/* 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_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE))
			entry->title = u16_strdup(u"U-Boot console");
		else
			entry->title = u16_strdup(u"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;
	u16 *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 = u16_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 '%ls'\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_CMD_BOOTMENU_ENTER_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"
);
