// SPDX-License-Identifier: GPL-2.0+
/*
 * Provide a menu of available bootflows and related options
 *
 * Copyright 2022 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#define LOG_CATEGORY UCLASS_BOOTSTD

#include <bootflow.h>
#include <bootstd.h>
#include <cli.h>
#include <dm.h>
#include <expo.h>
#include <malloc.h>
#include <menu.h>
#include <video_console.h>
#include <watchdog.h>
#include <linux/delay.h>
#include "bootflow_internal.h"

/**
 * struct menu_priv - information about the menu
 *
 * @num_bootflows: Number of bootflows in the menu
 */
struct menu_priv {
	int num_bootflows;
};

int bootflow_menu_new(struct expo **expp)
{
	struct udevice *last_bootdev;
	struct scene_obj_menu *menu;
	struct menu_priv *priv;
	struct bootflow *bflow;
	struct scene *scn;
	struct expo *exp;
	void *logo;
	int ret, i;

	priv = calloc(1, sizeof(*priv));
	if (!priv)
		return log_msg_ret("prv", -ENOMEM);

	ret = expo_new("bootflows", priv, &exp);
	if (ret)
		return log_msg_ret("exp", ret);

	ret = scene_new(exp, "main", MAIN, &scn);
	if (ret < 0)
		return log_msg_ret("scn", ret);

	ret |= scene_txt_str(scn, "prompt", OBJ_PROMPT, STR_PROMPT,
			     "UP and DOWN to choose, ENTER to select", NULL);

	ret = scene_menu(scn, "main", OBJ_MENU, &menu);
	ret |= scene_obj_set_pos(scn, OBJ_MENU, MARGIN_LEFT, 100);
	ret |= scene_txt_str(scn, "title", OBJ_MENU_TITLE, STR_MENU_TITLE,
			     "U-Boot - Boot Menu", NULL);
	ret |= scene_menu_set_title(scn, OBJ_MENU, OBJ_PROMPT);

	logo = video_get_u_boot_logo();
	if (logo) {
		ret |= scene_img(scn, "ulogo", OBJ_U_BOOT_LOGO, logo, NULL);
		ret |= scene_obj_set_pos(scn, OBJ_U_BOOT_LOGO, -4, 4);
	}

	ret |= scene_txt_str(scn, "cur_item", OBJ_POINTER, STR_POINTER, ">",
			     NULL);
	ret |= scene_menu_set_pointer(scn, OBJ_MENU, OBJ_POINTER);
	if (ret < 0)
		return log_msg_ret("new", -EINVAL);

	last_bootdev = NULL;
	for (ret = bootflow_first_glob(&bflow), i = 0; !ret && i < 36;
	     ret = bootflow_next_glob(&bflow), i++) {
		char str[2], *label, *key;
		uint preview_id;
		bool add_gap;

		if (bflow->state != BOOTFLOWST_READY)
			continue;

		*str = i < 10 ? '0' + i : 'A' + i - 10;
		str[1] = '\0';
		key = strdup(str);
		if (!key)
			return log_msg_ret("key", -ENOMEM);
		label = strdup(dev_get_parent(bflow->dev)->name);
		if (!label) {
			free(key);
			return log_msg_ret("nam", -ENOMEM);
		}

		add_gap = last_bootdev != bflow->dev;
		last_bootdev = bflow->dev;

		ret = expo_str(exp, "prompt", STR_POINTER, ">");
		ret |= scene_txt_str(scn, "label", ITEM_LABEL + i,
				      STR_LABEL + i, label, NULL);
		ret |= scene_txt_str(scn, "desc", ITEM_DESC + i, STR_DESC + i,
				    bflow->os_name ? bflow->os_name :
				    bflow->name, NULL);
		ret |= scene_txt_str(scn, "key", ITEM_KEY + i, STR_KEY + i, key,
				      NULL);
		preview_id = 0;
		if (bflow->logo) {
			preview_id = ITEM_PREVIEW + i;
			ret |= scene_img(scn, "preview", preview_id,
					     bflow->logo, NULL);
		}
		ret |= scene_menuitem(scn, OBJ_MENU, "item", ITEM + i,
					  ITEM_KEY + i, ITEM_LABEL + i,
					  ITEM_DESC + i, preview_id,
					  add_gap ? SCENEMIF_GAP_BEFORE : 0,
					  NULL);

		if (ret < 0)
			return log_msg_ret("itm", -EINVAL);
		priv->num_bootflows++;
	}

	ret = scene_arrange(scn);
	if (ret)
		return log_msg_ret("arr", ret);

	*expp = exp;

	return 0;
}

int bootflow_menu_apply_theme(struct expo *exp, ofnode node)
{
	struct menu_priv *priv = exp->priv;
	struct scene *scn;
	u32 font_size;
	int ret;

	log_debug("Applying theme %s\n", ofnode_get_name(node));
	scn = expo_lookup_scene_id(exp, MAIN);
	if (!scn)
		return log_msg_ret("scn", -ENOENT);

	/* Avoid error-checking optional items */
	if (!ofnode_read_u32(node, "font-size", &font_size)) {
		int i;

		log_debug("font size %d\n", font_size);
		scene_txt_set_font(scn, OBJ_PROMPT, NULL, font_size);
		scene_txt_set_font(scn, OBJ_POINTER, NULL, font_size);
		for (i = 0; i < priv->num_bootflows; i++) {
			ret = scene_txt_set_font(scn, ITEM_DESC + i, NULL,
						 font_size);
			if (ret)
				return log_msg_ret("des", ret);
			scene_txt_set_font(scn, ITEM_KEY + i, NULL, font_size);
			scene_txt_set_font(scn, ITEM_LABEL + i, NULL,
					   font_size);
		}
	}

	ret = scene_arrange(scn);
	if (ret)
		return log_msg_ret("arr", ret);

	return 0;
}

int bootflow_menu_run(struct bootstd_priv *std, bool text_mode,
		      struct bootflow **bflowp)
{
	struct cli_ch_state s_cch, *cch = &s_cch;
	struct bootflow *sel_bflow;
	struct udevice *dev;
	struct expo *exp;
	uint sel_id;
	bool done;
	int ret;

	cli_ch_init(cch);

	sel_bflow = NULL;
	*bflowp = NULL;

	ret = bootflow_menu_new(&exp);
	if (ret)
		return log_msg_ret("exp", ret);

	if (ofnode_valid(std->theme)) {
		ret = bootflow_menu_apply_theme(exp, std->theme);
		if (ret)
			return log_msg_ret("thm", ret);
	}

	/* For now we only support a video console */
	ret = uclass_first_device_err(UCLASS_VIDEO, &dev);
	if (ret)
		return log_msg_ret("vid", ret);
	ret = expo_set_display(exp, dev);
	if (ret)
		return log_msg_ret("dis", ret);

	ret = expo_set_scene_id(exp, MAIN);
	if (ret)
		return log_msg_ret("scn", ret);

	if (text_mode)
		expo_set_text_mode(exp, text_mode);

	done = false;
	do {
		struct expo_action act;
		int ichar, key;

		ret = expo_render(exp);
		if (ret)
			break;

		ichar = cli_ch_process(cch, 0);
		if (!ichar) {
			while (!ichar && !tstc()) {
				schedule();
				mdelay(2);
				ichar = cli_ch_process(cch, -ETIMEDOUT);
			}
			if (!ichar) {
				ichar = getchar();
				ichar = cli_ch_process(cch, ichar);
			}
		}

		key = 0;
		if (ichar) {
			key = bootmenu_conv_key(ichar);
			if (key == BKEY_NONE)
				key = ichar;
		}
		if (!key)
			continue;

		ret = expo_send_key(exp, key);
		if (ret)
			break;

		ret = expo_action_get(exp, &act);
		if (!ret) {
			switch (act.type) {
			case EXPOACT_SELECT:
				sel_id = act.select.id;
				done = true;
				break;
			case EXPOACT_QUIT:
				done = true;
				break;
			default:
				break;
			}
		}
	} while (!done);

	if (ret)
		return log_msg_ret("end", ret);

	if (sel_id) {
		struct bootflow *bflow;
		int i;

		for (ret = bootflow_first_glob(&bflow), i = 0; !ret && i < 36;
		     ret = bootflow_next_glob(&bflow), i++) {
			if (i == sel_id - ITEM) {
				sel_bflow = bflow;
				break;
			}
		}
	}

	expo_destroy(exp);

	if (!sel_bflow)
		return -EAGAIN;
	*bflowp = sel_bflow;

	return 0;
}
