// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2012, Google Inc.
 */

#include <common.h>
#include <command.h>
#include <dm.h>
#include <fs.h>
#include <part.h>
#include <sandbox_host.h>
#include <dm/device_compat.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
#include <linux/errno.h>

static int do_host_load(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	return do_load(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
}

static int do_host_ls(struct cmd_tbl *cmdtp, int flag, int argc,
		      char *const argv[])
{
	return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
}

static int do_host_size(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	return do_size(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
}

static int do_host_save(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
}

static int do_host_bind(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	bool removable = false;
	struct udevice *dev;
	const char *label;
	char *file;
	int ret;

	/* Skip 'bind' */
	argc--;
	argv++;
	if (argc < 2)
		return CMD_RET_USAGE;

	if (!strcmp(argv[0], "-r")) {
		removable = true;
		argc--;
		argv++;
	}

	if (argc > 2)
		return CMD_RET_USAGE;
	label = argv[0];
	file = argc > 1 ? argv[1] : NULL;

	ret = host_create_attach_file(label, file, removable, &dev);
	if (ret) {
		printf("Cannot create device / bind file\n");
		return CMD_RET_FAILURE;
	}

	return 0;
}

/**
 * parse_host_label() - Parse a device label or sequence number
 *
 * This shows an error if it returns NULL
 *
 * @label: String containing the label or sequence number
 * Returns: Associated device, or NULL if not found
 */
static struct udevice *parse_host_label(const char *label)
{
	struct udevice *dev;

	dev = host_find_by_label(label);
	if (!dev) {
		int devnum;
		char *ep;

		devnum = hextoul(label, &ep);
		if (*ep ||
		    uclass_find_device_by_seq(UCLASS_HOST, devnum, &dev)) {
			printf("No such device '%s'\n", label);
			return NULL;
		}
	}

	return dev;
}

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

	if (argc < 2)
		return CMD_RET_USAGE;

	label = argv[1];
	dev = parse_host_label(label);
	if (!dev)
		return CMD_RET_FAILURE;

	ret = host_detach_file(dev);
	if (ret) {
		printf("Cannot detach file (err=%d)\n", ret);
		return CMD_RET_FAILURE;
	}

	ret = device_unbind(dev);
	if (ret) {
		printf("Cannot attach file\n");
		ret = device_unbind(dev);
		if (ret)
			printf("Cannot unbind device '%s'\n", dev->name);
		return CMD_RET_FAILURE;
	}

	return 0;
}

static void show_host_dev(struct udevice *dev)
{
	struct host_sb_plat *plat = dev_get_plat(dev);
	struct blk_desc *desc;
	struct udevice *blk;
	int ret;

	printf("%3d ", dev_seq(dev));
	if (!plat->fd) {
		printf("Not bound to a backing file\n");
		return;
	}
	ret = blk_get_from_parent(dev, &blk);
	if (ret)  /* cannot happen */
		return;

	desc = dev_get_uclass_plat(blk);
	printf("%12lu %-15s %s\n", (unsigned long)desc->lba, plat->label,
	       plat->filename);
}

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

	if (argc < 1)
		return CMD_RET_USAGE;

	dev = NULL;
	if (argc >= 2) {
		dev = parse_host_label(argv[1]);
		if (!dev)
			return CMD_RET_FAILURE;
	}

	printf("%3s %12s %-15s %s\n", "dev", "blocks", "label", "path");
	if (dev) {
		show_host_dev(dev);
	} else {
		struct uclass *uc;

		uclass_id_foreach_dev(UCLASS_HOST, dev, uc)
			show_host_dev(dev);
	}

	return 0;
}

static int do_host_dev(struct cmd_tbl *cmdtp, int flag, int argc,
		       char *const argv[])
{
	struct udevice *dev;
	const char *label;

	if (argc < 1 || argc > 3)
		return CMD_RET_USAGE;

	if (argc == 1) {
		struct host_sb_plat *plat;

		dev = host_get_cur_dev();
		if (!dev) {
			printf("No current host device\n");
			return CMD_RET_FAILURE;
		}
		plat = dev_get_plat(dev);
		printf("Current host device: %d: %s\n", dev_seq(dev),
		       plat->label);
		return 0;
	}

	label = argv[1];
	dev = parse_host_label(argv[1]);
	if (!dev)
		return CMD_RET_FAILURE;

	host_set_cur_dev(dev);

	return 0;
}

static struct cmd_tbl cmd_host_sub[] = {
	U_BOOT_CMD_MKENT(load, 7, 0, do_host_load, "", ""),
	U_BOOT_CMD_MKENT(ls, 3, 0, do_host_ls, "", ""),
	U_BOOT_CMD_MKENT(save, 6, 0, do_host_save, "", ""),
	U_BOOT_CMD_MKENT(size, 3, 0, do_host_size, "", ""),
	U_BOOT_CMD_MKENT(bind, 4, 0, do_host_bind, "", ""),
	U_BOOT_CMD_MKENT(unbind, 4, 0, do_host_unbind, "", ""),
	U_BOOT_CMD_MKENT(info, 3, 0, do_host_info, "", ""),
	U_BOOT_CMD_MKENT(dev, 0, 1, do_host_dev, "", ""),
};

static int do_host(struct cmd_tbl *cmdtp, int flag, int argc,
		   char *const argv[])
{
	struct cmd_tbl *c;

	/* Skip past 'host' */
	argc--;
	argv++;

	c = find_cmd_tbl(argv[0], cmd_host_sub, ARRAY_SIZE(cmd_host_sub));

	if (c)
		return c->cmd(cmdtp, flag, argc, argv);
	else
		return CMD_RET_USAGE;
}

U_BOOT_CMD(
	host, 8, 1, do_host,
	"Miscellaneous host commands",
	"load hostfs - <addr> <filename> [<bytes> <offset>]  - "
		"load a file from host\n"
	"host ls hostfs - <filename>                    - list files on host\n"
	"host save hostfs - <addr> <filename> <bytes> [<offset>] - "
		"save a file to host\n"
	"host size hostfs - <filename> - determine size of file on host\n"
	"host bind [-r] <label> [<filename>] - bind \"host\" device to file\n"
	"     -r = mark as removable\n"
	"host unbind <label>     - unbind file from \"host\" device\n"
	"host info [<label>]     - show device binding & info\n"
	"host dev [<label>]      - set or retrieve the current host device\n"
	"host commands use the \"hostfs\" device. The \"host\" device is used\n"
	"with standard IO commands such as fatls or ext2load"
);
