/* Copyright 2020 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Firmware screen definitions.
 */

#include "2api.h"
#include "2common.h"
#include "2misc.h"
#include "2nvstorage.h"
#include "2ui.h"
#include "2ui_private.h"
#include "vboot_api.h"
#include "vboot_kernel.h"

#define MENU_ITEMS(a) ((struct vb2_menu){ \
	.num_items = ARRAY_SIZE(a), \
	.items = a, \
})

#define LANGUAGE_SELECT_ITEM { \
	.text = "Language selection", \
	.target = VB2_SCREEN_LANGUAGE_SELECT, \
	.is_language_select = 1, \
}

#define ADVANCED_OPTIONS_ITEM { \
	.text = "Advanced options", \
	.target = VB2_SCREEN_ADVANCED_OPTIONS, \
}

/******************************************************************************/
/* VB2_SCREEN_BLANK */

static const struct vb2_screen_info blank_screen = {
	.id = VB2_SCREEN_BLANK,
	.name = "Blank",
};

/******************************************************************************/
/* VB2_SCREEN_LANGUAGE_SELECT */

static vb2_error_t language_select_action(struct vb2_ui_context *ui)
{
	vb2_error_t rv;
	ui->locale_id = ui->state.selected_item;
	VB2_DEBUG("Locale changed to %u\n", ui->locale_id);

	/* Write locale id back to nvdata. */
	vb2_nv_set(ui->ctx, VB2_NV_LOCALIZATION_INDEX, ui->locale_id);

	/* Commit nvdata changes immediately, in case of three-finger salute
	   reboot.  Ignore commit errors in recovery mode. */
	rv = vb2ex_commit_data(ui->ctx);
	if (rv && !(ui->ctx->flags & VB2_CONTEXT_RECOVERY_MODE))
		return rv;

	return vb2_ui_change_root(ui);
}

const struct vb2_menu *get_language_menu(struct vb2_ui_context *ui)
{
	int i;
	uint32_t num_locales;
	struct vb2_menu_item *items;

	if (ui->language_menu.num_items > 0)
		return &ui->language_menu;

	num_locales = vb2ex_get_locale_count();
	if (num_locales == 0) {
		VB2_DEBUG("WARNING: No locales available; assuming 1 locale\n");
		num_locales = 1;
	}

	items = malloc(num_locales * sizeof(struct vb2_menu_item));
	if (!items) {
		VB2_DEBUG("ERROR: malloc failed for language items\n");
		return NULL;
	}

	for (i = 0; i < num_locales; i++) {
		items[i].text = "Some language";
		items[i].action = language_select_action;
	}

	ui->language_menu.num_items = num_locales;
	ui->language_menu.items = items;
	return &ui->language_menu;
}

static vb2_error_t language_select_init(struct vb2_ui_context *ui)
{
	const struct vb2_menu *menu = get_menu(ui);
	if (menu->num_items == 0) {
		VB2_DEBUG("ERROR: No menu items found; "
			  "rejecting entering language selection screen\n");
		return vb2_ui_change_root(ui);
	}
	if (ui->locale_id < menu->num_items) {
		ui->state.selected_item = ui->locale_id;
	} else {
		VB2_DEBUG("WARNING: Current locale not found in menu items; "
			  "initializing selected_item to 0\n");
		ui->state.selected_item = 0;
	}
	return VB2_REQUEST_UI_CONTINUE;
}

static const struct vb2_screen_info language_select_screen = {
	.id = VB2_SCREEN_LANGUAGE_SELECT,
	.name = "Language selection screen",
	.init = language_select_init,
	.get_menu = get_language_menu,
};

/******************************************************************************/
/* VB2_SCREEN_RECOVERY_BROKEN */

static const struct vb2_menu_item recovery_broken_items[] = {
	LANGUAGE_SELECT_ITEM,
	ADVANCED_OPTIONS_ITEM,
};

static const struct vb2_screen_info recovery_broken_screen = {
	.id = VB2_SCREEN_RECOVERY_BROKEN,
	.name = "Recover broken device",
	.menu = MENU_ITEMS(recovery_broken_items),
};

/******************************************************************************/
/* VB2_SCREEN_ADVANCED_OPTIONS */

#define ADVANCED_OPTIONS_ITEM_DEVELOPER_MODE 1
#define ADVANCED_OPTIONS_ITEM_BACK 2

vb2_error_t advanced_options_init(struct vb2_ui_context *ui)
{
	ui->state.selected_item = ADVANCED_OPTIONS_ITEM_DEVELOPER_MODE;
	if (vb2_get_sd(ui->ctx)->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) {
		ui->state.disabled_item_mask |=
			1 << ADVANCED_OPTIONS_ITEM_DEVELOPER_MODE;
		ui->state.selected_item = ADVANCED_OPTIONS_ITEM_BACK;
	}

	return VB2_REQUEST_UI_CONTINUE;
}

static const struct vb2_menu_item advanced_options_items[] = {
	LANGUAGE_SELECT_ITEM,
	[ADVANCED_OPTIONS_ITEM_DEVELOPER_MODE] = {
		.text = "Enable developer mode",
		.target = VB2_SCREEN_RECOVERY_TO_DEV,
	},
	[ADVANCED_OPTIONS_ITEM_BACK] = {
		.text = "Back",
		.action = vb2_ui_change_root,
	},
};

static const struct vb2_screen_info advanced_options_screen = {
	.id = VB2_SCREEN_ADVANCED_OPTIONS,
	.name = "Advanced options",
	.init = advanced_options_init,
	.menu = MENU_ITEMS(advanced_options_items),
};

/******************************************************************************/
/* VB2_SCREEN_RECOVERY_SELECT */

#define RECOVERY_SELECT_ITEM_PHONE 1
#define RECOVERY_SELECT_ITEM_EXTERNAL_DISK 2

vb2_error_t recovery_select_init(struct vb2_ui_context *ui)
{
	ui->state.selected_item = RECOVERY_SELECT_ITEM_PHONE;
	if (!vb2api_phone_recovery_enabled(ui->ctx)) {
		VB2_DEBUG("WARNING: Phone recovery not available\n");
		ui->state.disabled_item_mask |=
			1 << RECOVERY_SELECT_ITEM_PHONE;
		ui->state.selected_item = RECOVERY_SELECT_ITEM_EXTERNAL_DISK;
	}
	return VB2_REQUEST_UI_CONTINUE;
}

static const struct vb2_menu_item recovery_select_items[] = {
	LANGUAGE_SELECT_ITEM,
	[RECOVERY_SELECT_ITEM_PHONE] = {
		.text = "Recovery using phone",
		.target = VB2_SCREEN_RECOVERY_PHONE_STEP1,
	},
	[RECOVERY_SELECT_ITEM_EXTERNAL_DISK] = {
		.text = "Recovery using external disk",
		.target = VB2_SCREEN_RECOVERY_DISK_STEP1,
	},
	ADVANCED_OPTIONS_ITEM,
};

static const struct vb2_screen_info recovery_select_screen = {
	.id = VB2_SCREEN_RECOVERY_SELECT,
	.name = "Recovery method selection",
	.init = recovery_select_init,
	.menu = MENU_ITEMS(recovery_select_items),
};

/******************************************************************************/
/* VB2_SCREEN_RECOVERY_INVALID */

static const struct vb2_menu_item recovery_invalid_items[] = {
	LANGUAGE_SELECT_ITEM,
};

static const struct vb2_screen_info recovery_invalid_screen = {
	.id = VB2_SCREEN_RECOVERY_INVALID,
	.name = "Invalid recovery inserted",
	.menu = MENU_ITEMS(recovery_invalid_items),
};

/******************************************************************************/
/* VB2_SCREEN_RECOVERY_TO_DEV */

#define RECOVERY_TO_DEV_ITEM_CONFIRM 1
#define RECOVERY_TO_DEV_ITEM_CANCEL 2

vb2_error_t recovery_to_dev_init(struct vb2_ui_context *ui)
{
	if (vb2_get_sd(ui->ctx)->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) {
		VB2_DEBUG("Dev mode already enabled?\n");
		return vb2_ui_change_root(ui);
	}

	if (!PHYSICAL_PRESENCE_KEYBOARD && vb2ex_physical_presence_pressed()) {
		VB2_DEBUG("Presence button stuck?\n");
		return vb2_ui_change_root(ui);
	}

	ui->state.selected_item = RECOVERY_TO_DEV_ITEM_CONFIRM;

	/* Disable "Confirm" button for other physical presence types. */
	if (!PHYSICAL_PRESENCE_KEYBOARD) {
		ui->state.disabled_item_mask |=
			1 << RECOVERY_TO_DEV_ITEM_CONFIRM;
		ui->state.selected_item = RECOVERY_TO_DEV_ITEM_CANCEL;
	}

	ui->physical_presence_button_pressed = 0;

	return VB2_REQUEST_UI_CONTINUE;
}

static vb2_error_t recovery_to_dev_finalize(struct vb2_ui_context *ui)
{
	VB2_DEBUG("Physical presence confirmed!\n");

	/* Sanity check, should never happen. */
	if (ui->state.screen->id != VB2_SCREEN_RECOVERY_TO_DEV ||
	    (vb2_get_sd(ui->ctx)->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) ||
	    !vb2_allow_recovery(ui->ctx)) {
		VB2_DEBUG("ERROR: Dev transition sanity check failed\n");
		return VB2_REQUEST_UI_CONTINUE;
	}

	VB2_DEBUG("Enabling dev mode and rebooting...\n");
	vb2_enable_developer_mode(ui->ctx);
	return VB2_REQUEST_REBOOT_EC_TO_RO;
}

vb2_error_t recovery_to_dev_confirm_action(struct vb2_ui_context *ui)
{
	if (!ui->key_trusted) {
		VB2_DEBUG("Reject untrusted %s confirmation\n",
			  ui->key == VB_KEY_ENTER ? "ENTER" : "POWER");
		return VB2_REQUEST_UI_CONTINUE;
	}
	return recovery_to_dev_finalize(ui);
}

vb2_error_t recovery_to_dev_action(struct vb2_ui_context *ui)
{
	int pressed;

	if (ui->key == ' ') {
		VB2_DEBUG("SPACE means cancel dev mode transition\n");
		return vb2_ui_change_root(ui);
	}

	/* Keyboard physical presence case covered by "Confirm" action. */
	if (PHYSICAL_PRESENCE_KEYBOARD)
		return VB2_REQUEST_UI_CONTINUE;

	pressed = vb2ex_physical_presence_pressed();
	if (pressed) {
		VB2_DEBUG("Physical presence button pressed, "
			  "awaiting release\n");
		ui->physical_presence_button_pressed = 1;
		return VB2_REQUEST_UI_CONTINUE;
	}
	if (!ui->physical_presence_button_pressed)
		return VB2_REQUEST_UI_CONTINUE;
	VB2_DEBUG("Physical presence button released\n");

	return recovery_to_dev_finalize(ui);
}

static const struct vb2_menu_item recovery_to_dev_items[] = {
	LANGUAGE_SELECT_ITEM,
	[RECOVERY_TO_DEV_ITEM_CONFIRM] = {
		.text = "Confirm",
		.action = recovery_to_dev_confirm_action,
	},
	[RECOVERY_TO_DEV_ITEM_CANCEL] = {
		.text = "Cancel",
		.action = vb2_ui_change_root,
	},
};

static const struct vb2_screen_info recovery_to_dev_screen = {
	.id = VB2_SCREEN_RECOVERY_TO_DEV,
	.name = "Transition to developer mode",
	.init = recovery_to_dev_init,
	.action = recovery_to_dev_action,
	.menu = MENU_ITEMS(recovery_to_dev_items),
};

/******************************************************************************/
/* VB2_SCREEN_RECOVERY_PHONE_STEP1 */

static const struct vb2_menu_item recovery_phone_step1_items[] = {
	LANGUAGE_SELECT_ITEM,
};

static const struct vb2_screen_info recovery_phone_step1_screen = {
	.id = VB2_SCREEN_RECOVERY_PHONE_STEP1,
	.name = "Phone recovery step 1",
	.menu = MENU_ITEMS(recovery_phone_step1_items),
};

/******************************************************************************/
/* VB2_SCREEN_RECOVERY_DISK_STEP1 */

static const struct vb2_menu_item recovery_disk_step1_items[] = {
	LANGUAGE_SELECT_ITEM,
};

static const struct vb2_screen_info recovery_disk_step1_screen = {
	.id = VB2_SCREEN_RECOVERY_DISK_STEP1,
	.name = "Disk recovery step 1",
	.menu = MENU_ITEMS(recovery_disk_step1_items),
};

/******************************************************************************/
/* VB2_SCREEN_DEVELOPER_MODE */

#define DEVELOPER_MODE_ITEM_RETURN_TO_SECURE 1
#define DEVELOPER_MODE_ITEM_BOOT_INTERNAL 2
#define DEVELOPER_MODE_ITEM_BOOT_EXTERNAL 3

vb2_error_t developer_mode_init(struct vb2_ui_context *ui)
{
	enum vb2_dev_default_boot default_boot =
		vb2_get_dev_boot_target(ui->ctx);

	/* Get me outta here! */
	if (!vb2_dev_boot_allowed(ui->ctx))
		vb2_ui_change_screen(ui, VB2_SCREEN_DEVELOPER_TO_NORM);

	/* Don't show "Return to secure mode" button if GBB forces dev mode. */
	if (vb2_get_gbb(ui->ctx)->flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON)
		ui->state.disabled_item_mask |=
			1 << DEVELOPER_MODE_ITEM_RETURN_TO_SECURE;

	/* Don't show "Boot from external disk" button if not allowed. */
	if (!vb2_dev_boot_usb_allowed(ui->ctx))
		ui->state.disabled_item_mask |=
			1 << DEVELOPER_MODE_ITEM_BOOT_EXTERNAL;

	/* Choose the default selection. */
	switch (default_boot) {
	case VB2_DEV_DEFAULT_BOOT_USB:
		ui->state.selected_item = DEVELOPER_MODE_ITEM_BOOT_EXTERNAL;
		break;
	default:
		ui->state.selected_item = DEVELOPER_MODE_ITEM_BOOT_INTERNAL;
		break;
	}

	ui->start_time = vb2ex_mtime();

	return VB2_REQUEST_UI_CONTINUE;
}

vb2_error_t vb2_ui_developer_mode_boot_internal_action(
	struct vb2_ui_context *ui)
{
	if (!(ui->ctx->flags & VB2_CONTEXT_DEVELOPER_MODE) ||
	    !vb2_dev_boot_allowed(ui->ctx)) {
		VB2_DEBUG("ERROR: Dev mode internal boot not allowed\n");
		return VB2_REQUEST_UI_CONTINUE;
	}

	VB2_TRY(VbTryLoadKernel(ui->ctx, VB_DISK_FLAG_FIXED));
	return VB2_SUCCESS;
}

vb2_error_t vb2_ui_developer_mode_boot_external_action(
	struct vb2_ui_context *ui)
{
	/* Sanity check, should never happen. */
	if (!(ui->ctx->flags & VB2_CONTEXT_DEVELOPER_MODE) ||
	    !vb2_dev_boot_allowed(ui->ctx) ||
	    !vb2_dev_boot_usb_allowed(ui->ctx)) {
		VB2_DEBUG("ERROR: Dev mode external boot not allowed\n");
		return VB2_REQUEST_UI_CONTINUE;
	}

	if (VbTryLoadKernel(ui->ctx, VB_DISK_FLAG_REMOVABLE)) {
		VB2_DEBUG("ERROR: Dev mode external boot failed\n");
		return VB2_REQUEST_UI_CONTINUE;
	}

	return VB2_SUCCESS;
}

vb2_error_t developer_mode_action(struct vb2_ui_context *ui)
{
	struct vb2_gbb_header *gbb = vb2_get_gbb(ui->ctx);
	const int use_short = gbb->flags & VB2_GBB_FLAG_DEV_SCREEN_SHORT_DELAY;
	uint64_t elapsed;

	/* Once any user interaction occurs, stop the timer. */
	if (ui->key)
		ui->disable_timer = 1;
	if (ui->disable_timer)
		return VB2_REQUEST_UI_CONTINUE;

	elapsed = vb2ex_mtime() - ui->start_time;

	/* If we're using short delay, wait 2 seconds and don't beep. */
	if (use_short && elapsed > 2 * VB2_MSEC_PER_SEC) {
		VB2_DEBUG("Booting default target after 2s\n");
		ui->disable_timer = 1;
		return vb2_ui_menu_select(ui);
	}

	/* Otherwise, beep at 20 and 20.5 seconds. */
	if ((ui->beep_count == 0 && elapsed > 20 * VB2_MSEC_PER_SEC) ||
	    (ui->beep_count == 1 && elapsed > 20 * VB2_MSEC_PER_SEC + 500)) {
		vb2ex_beep(250, 400);
		ui->beep_count++;
	}

	/* Stop after 30 seconds. */
	if (elapsed > 30 * VB2_MSEC_PER_SEC) {
		VB2_DEBUG("Booting default target after 30s\n");
		ui->disable_timer = 1;
		return vb2_ui_menu_select(ui);
	}

	return VB2_REQUEST_UI_CONTINUE;
}

static const struct vb2_menu_item developer_mode_items[] = {
	LANGUAGE_SELECT_ITEM,
	[DEVELOPER_MODE_ITEM_RETURN_TO_SECURE] = {
		.text = "Return to secure mode",
		.target = VB2_SCREEN_DEVELOPER_TO_NORM,
	},
	[DEVELOPER_MODE_ITEM_BOOT_INTERNAL] = {
		.text = "Boot from internal disk",
		.action = vb2_ui_developer_mode_boot_internal_action,
	},
	[DEVELOPER_MODE_ITEM_BOOT_EXTERNAL] = {
		.text = "Boot from external disk",
		.action = vb2_ui_developer_mode_boot_external_action,
	},
	ADVANCED_OPTIONS_ITEM,
};

static const struct vb2_screen_info developer_mode_screen = {
	.id = VB2_SCREEN_DEVELOPER_MODE,
	.name = "Developer mode",
	.init = developer_mode_init,
	.action = developer_mode_action,
	.menu = MENU_ITEMS(developer_mode_items),
};

/******************************************************************************/
/* VB2_SCREEN_DEVELOPER_TO_NORM */

vb2_error_t developer_to_norm_action(struct vb2_ui_context *ui)
{
	if (vb2_get_gbb(ui->ctx)->flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON) {
		VB2_DEBUG("ERROR: dev mode forced by GBB flag\n");
		return VB2_REQUEST_UI_CONTINUE;
	}

	VB2_DEBUG("Leaving dev mode\n");
	vb2_nv_set(ui->ctx, VB2_NV_DISABLE_DEV_REQUEST, 1);
	return VB2_REQUEST_REBOOT;
}

static const struct vb2_menu_item developer_to_norm_items[] = {
	LANGUAGE_SELECT_ITEM,
	{
		.text = "Confirm",
		.action = developer_to_norm_action,
	},
	{
		.text = "Cancel",
		.action = vb2_ui_change_root,
	},
};

static const struct vb2_screen_info developer_to_norm_screen = {
	.id = VB2_SCREEN_DEVELOPER_TO_NORM,
	.name = "Transition to normal mode",
	.menu = MENU_ITEMS(developer_to_norm_items),
};

/******************************************************************************/
/*
 * TODO(chromium:1035800): Refactor UI code across vboot and depthcharge.
 * Currently vboot and depthcharge maintain their own copies of menus/screens.
 * vboot detects keyboard input and controls the navigation among different menu
 * items and screens, while depthcharge performs the actual rendering of each
 * screen, based on the menu information passed from vboot.
 */
static const struct vb2_screen_info *screens[] = {
	&blank_screen,
	&language_select_screen,
	&recovery_broken_screen,
	&advanced_options_screen,
	&recovery_select_screen,
	&recovery_invalid_screen,
	&recovery_to_dev_screen,
	&recovery_phone_step1_screen,
	&recovery_disk_step1_screen,
	&developer_mode_screen,
	&developer_to_norm_screen,
};

const struct vb2_screen_info *vb2_get_screen_info(enum vb2_screen id)
{
	int i;
	for (i = 0; i < ARRAY_SIZE(screens); i++) {
		if (screens[i]->id == id)
			return screens[i];
	}
	return NULL;
}
