// SPDX-License-Identifier: GPL-2.0+
/*
 * 'bootdev' command
 *
 * Copyright 2021 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#include <bootdev.h>
#include <bootflow.h>
#include <bootstd.h>
#include <command.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>

static int bootdev_check_state(struct bootstd_priv **stdp)
{
	struct bootstd_priv *std;
	int ret;

	ret = bootstd_get_priv(&std);
	if (ret)
		return ret;
	if (!std->cur_bootdev) {
		printf("Please use 'bootdev select' first\n");
		return -ENOENT;
	}
	*stdp = std;

	return 0;
}

static int do_bootdev_list(struct cmd_tbl *cmdtp, int flag, int argc,
			   char *const argv[])
{
	bool probe;

	probe = argc >= 2 && !strcmp(argv[1], "-p");
	bootdev_list(probe);

	return 0;
}

static int do_bootdev_select(struct cmd_tbl *cmdtp, int flag, int argc,
			     char *const argv[])
{
	struct bootstd_priv *std;
	struct udevice *dev;
	int ret;

	ret = bootstd_get_priv(&std);
	if (ret)
		return CMD_RET_FAILURE;
	if (argc < 2) {
		std->cur_bootdev = NULL;
		return 0;
	}
	if (bootdev_find_by_any(argv[1], &dev, NULL))
		return CMD_RET_FAILURE;

	std->cur_bootdev = dev;

	return 0;
}

static int do_bootdev_info(struct cmd_tbl *cmdtp, int flag, int argc,
			   char *const argv[])
{
	struct bootstd_priv *priv;
	struct bootflow *bflow;
	int ret, i, num_valid;
	struct udevice *dev;
	bool probe;

	probe = argc >= 2 && !strcmp(argv[1], "-p");

	ret = bootdev_check_state(&priv);
	if (ret)
		return CMD_RET_FAILURE;

	dev = priv->cur_bootdev;

	/* Count the number of bootflows, including how many are valid */
	num_valid = 0;
	for (ret = bootdev_first_bootflow(dev, &bflow), i = 0;
	     !ret;
	     ret = bootdev_next_bootflow(&bflow), i++)
		num_valid += bflow->state == BOOTFLOWST_READY;

	/*
	 * Prove the device, if requested, otherwise assume that there is no
	 * error
	 */
	ret = 0;
	if (probe)
		ret = device_probe(dev);

	printf("Name:      %s\n", dev->name);
	printf("Sequence:  %d\n", dev_seq(dev));
	printf("Status:    %s\n", ret ? simple_itoa(-ret) : device_active(dev) ?
		"Probed" : "OK");
	printf("Uclass:    %s\n", dev_get_uclass_name(dev_get_parent(dev)));
	printf("Bootflows: %d (%d valid)\n", i, num_valid);

	return 0;
}

static int do_bootdev_hunt(struct cmd_tbl *cmdtp, int flag, int argc,
			   char *const argv[])
{
	struct bootstd_priv *priv;
	const char *spec = NULL;
	bool list = false;
	int ret = 0;

	if (argc >= 2) {
		if (!strcmp(argv[1], "-l"))
			list = true;
		else
			spec = argv[1];
	}

	ret = bootstd_get_priv(&priv);
	if (ret)
		return ret;
	if (list) {
		bootdev_list_hunters(priv);
	} else {
		ret = bootdev_hunt(spec, true);
		if (ret) {
			printf("Failed (err=%dE)\n", ret);

			return CMD_RET_FAILURE;
		}
	}

	return 0;
}

U_BOOT_LONGHELP(bootdev,
	"list [-p]         - list all available bootdevs (-p to probe)\n"
	"bootdev hunt [-l|<spec>]  - use hunt drivers to find bootdevs\n"
	"bootdev select <bd>       - select a bootdev by name | label | seq\n"
	"bootdev info [-p]         - show information about a bootdev (-p to probe)");

U_BOOT_CMD_WITH_SUBCMDS(bootdev, "Boot devices", bootdev_help_text,
	U_BOOT_SUBCMD_MKENT(list, 2, 1, do_bootdev_list),
	U_BOOT_SUBCMD_MKENT(hunt, 2, 1, do_bootdev_hunt),
	U_BOOT_SUBCMD_MKENT(select, 2, 1, do_bootdev_select),
	U_BOOT_SUBCMD_MKENT(info, 2, 1, do_bootdev_info));
