// SPDX-License-Identifier: GPL-2.0+

#include <command.h>
#include <env.h>
#include <fs.h>
#include <pxe_utils.h>
#include <vsprintf.h>

/**
 * struct sysboot_info - useful information for sysboot helpers
 *
 * @fstype: Filesystem type (FS_TYPE_...)
 * @ifname: Interface name (e.g. "ide", "scsi")
 * @dev_part_str is in the format:
 *	<dev>.<hw_part>:<part> where <dev> is the device number,
 *	<hw_part> is the optional hardware partition number and
 *	<part> is the partition number
 */
struct sysboot_info {
	int fstype;
	const char *ifname;
	const char *dev_part_str;
};

static int sysboot_read_file(struct pxe_context *ctx, const char *file_path,
			     char *file_addr, enum bootflow_img_t type,
			     ulong *sizep)
{
	struct sysboot_info *info = ctx->userdata;
	loff_t len_read;
	ulong addr;
	int ret;

	addr = simple_strtoul(file_addr, NULL, 16);
	ret = fs_set_blk_dev(info->ifname, info->dev_part_str, info->fstype);
	if (ret)
		return ret;
	ret = fs_read(file_path, addr, 0, 0, &len_read);
	if (ret)
		return ret;
	*sizep = len_read;

	return 0;
}

/*
 * Boots a system using a local disk syslinux/extlinux file
 *
 * Returns 0 on success, 1 on error.
 */
static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
		      char *const argv[])
{
	unsigned long pxefile_addr_r;
	struct pxe_context ctx;
	char *pxefile_addr_str;
	struct sysboot_info info;
	char *filename;
	int prompt = 0;
	int ret;

	if (argc > 1 && strstr(argv[1], "-p")) {
		prompt = 1;
		argc--;
		argv++;
	}

	if (argc < 4)
		return cmd_usage(cmdtp);

	if (argc < 5) {
		pxefile_addr_str = from_env("pxefile_addr_r");
		if (!pxefile_addr_str)
			return 1;
	} else {
		pxefile_addr_str = argv[4];
	}

	if (argc < 6) {
		filename = env_get("bootfile");
		if (!filename) {
			printf("Specify a filename or set the ${bootfile} environment variable\n");
			return 1;
		}
	} else {
		filename = argv[5];
		env_set("bootfile", filename);
	}

	if (strstr(argv[3], "ext2")) {
		info.fstype = FS_TYPE_EXT;
	} else if (strstr(argv[3], "fat")) {
		info.fstype = FS_TYPE_FAT;
	} else if (strstr(argv[3], "any")) {
		info.fstype = FS_TYPE_ANY;
	} else {
		printf("Invalid filesystem: %s\n", argv[3]);
		return 1;
	}
	info.ifname = argv[1];
	info.dev_part_str = argv[2];

	if (strict_strtoul(pxefile_addr_str, 16, &pxefile_addr_r) < 0) {
		printf("Invalid pxefile address: %s\n", pxefile_addr_str);
		return 1;
	}

	if (pxe_setup_ctx(&ctx, cmdtp, sysboot_read_file, &info, true,
			  filename, false, false)) {
		printf("Out of memory\n");
		return CMD_RET_FAILURE;
	}

	if (get_pxe_file(&ctx, filename, pxefile_addr_r)
	    < 0) {
		printf("Error reading config file\n");
		pxe_destroy_ctx(&ctx);
		return 1;
	}

	ret = pxe_process(&ctx, pxefile_addr_r, prompt);
	pxe_destroy_ctx(&ctx);
	if (ret)
		return CMD_RET_FAILURE;

	return 0;
}

U_BOOT_CMD(sysboot, 7, 1, do_sysboot,
	   "command to get and boot from syslinux files",
	   "[-p] <interface> <dev[:part]> <ext2|fat|any> [addr] [filename]\n"
	   "    - load and parse syslinux menu file 'filename' from ext2, fat\n"
	   "      or any filesystem on 'dev' on 'interface' to address 'addr'"
);
