#include <command.h>
#include <common.h>
#include <fs.h>
#include <stdlib.h>

#define PERSIST_FILE "/property/persistent_properties"

/* protobuf: A wire type of 2 (length-delimited) means that the value is a
 * varint encoded length followed by the specified number of bytes of data. */
#define WIRE_TYPE_LENGTH_DELIMITED 0x12
#define WIRE_TYPE_MULTIPLE 0xa

struct property_header {
	unsigned char magic;
	unsigned char size;
	char data[];
} __attribute__((packed));

struct property_field {
	struct property_header hdr;
	char string[];
} __attribute__((packed));

#define PROPERTY_MAX_SIZE (255 + 1)
struct android_property {
	char key[PROPERTY_MAX_SIZE];
	char val[PROPERTY_MAX_SIZE];
};

struct aprop_data {
	int mmc_dev; /* mmc device we load PERSIST_FILE from */
	int mmc_part; /* mmc partition we load PERSIST_FILE from */
	int count; /* amount of parsed Android persistent properties */
	struct android_property
		*cache; /* cache of parsed Android persistent properties */
};

static struct aprop_data aprop = {
	.mmc_dev = -1,
	.mmc_part = -1,
	.count = -1,
	.cache = NULL,
};

enum aprop_cmd {
	APROP_CMD_LOAD,
	APROP_CMD_GET,
	APROP_CMD_SET,
	APROP_CMD_TEST,
	APROP_CMD_DUMP,
	APROP_CMD_STORE,
};

static int aprop_cmd_get(char *cmd)
{
	if (!strcmp(cmd, "load"))
		return APROP_CMD_LOAD;
	if (!strcmp(cmd, "get"))
		return APROP_CMD_GET;
	if (!strcmp(cmd, "set"))
		return APROP_CMD_SET;
	if (!strcmp(cmd, "test"))
		return APROP_CMD_TEST;
	if (!strcmp(cmd, "dump"))
		return APROP_CMD_DUMP;
	if (!strcmp(cmd, "store"))
		return APROP_CMD_STORE;
	else
		return -1;
}

static int aprop_is_misused(int argc, char *const argv[])
{
	int cmd = aprop_cmd_get(argv[0]);

	switch (cmd) {
	case APROP_CMD_LOAD:
		if (argc != 3)
			goto err;
		break;
	case APROP_CMD_GET:
		if (argc != 2)
			goto err;
		break;
	case APROP_CMD_SET:
		if (argc != 3)
			goto err;
		break;
	case APROP_CMD_TEST:
		if (argc != 4)
			goto err;
		break;
	case APROP_CMD_DUMP:
	case APROP_CMD_STORE:
		if (argc != 1)
			goto err;
		break;
	default:
		printf("Error: 'aprop %s' not supported\n", argv[0]);
		return -1;
	}

	if (cmd != APROP_CMD_LOAD &&
	    (aprop.mmc_dev < 0 || aprop.mmc_part < 0)) {
		printf("Error: Please, 'load' first!\n");
		return -1;
	}

	return 0;
err:
	printf("Error: Bad usage of 'aprop %s'\n", argv[0]);

	return -1;
}

/**
 * Computes the amount of elements (struct android_property) present in
 * a buffer corresponding to Android persistent property file
 *
 * @buffer: a valid buffer read from PERSIST_FILE
 * @size: buffer size (in bytes)
 */
static int aprop_count_from_buf(unsigned long buffer, loff_t size)
{
	struct property_header *hdr;
	unsigned long end = buffer + size;
	int count = 0;

	while (buffer < end) {
		hdr = (struct property_header *)buffer;
		buffer += hdr->size + sizeof(*hdr);
		count += 1;
	}

	return count;
}

/**
 * Deserializes a buffer into an Android property cache
 * This is a well known format described in protobuf here:
 * https://android.googlesource.com/platform/system/core/+/master/init/persistent_properties.proto
 *
 * @buf_location: a valid buffer read from PERSIST_FILE
 * @count: the amount of items in the cache
 * @cache: a valid android property cache, allocatd by caller
 */
static void aprop_deserialize_buf(ulong buf_location, int count,
			    struct android_property *cache)
{
	struct property_header *hdr;
	struct property_field *field;

	for (int i = 0; i < count; ++i) {
		hdr = (struct property_header *)buf_location;

		field = (struct property_field *)hdr->data;
		strncpy(cache[i].key, field->string, field->hdr.size);
		cache[i].key[field->hdr.size] = '\0';

		field = (struct property_field *)(field->string +
						  field->hdr.size);
		strncpy(cache[i].val, field->string, field->hdr.size);
		cache[i].val[field->hdr.size] = '\0';

		buf_location += hdr->size + sizeof(*hdr);
	}
}

/**
 * Computes the amount of bytes we need on disk to store the current
 * Android property cache.
 *
 * @cache: a valid android property cache (usually aprop.cache)
 * @count: the amount of items in the cache
 */
static size_t aprop_bufsize_for_cache(struct android_property *cache, int count)
{
	size_t bytes = 0;

	for (int i = 0; i < count; i++) {
		size_t bytes_key = strlen(cache[i].key);
		size_t bytes_val = strlen(cache[i].val);

		bytes += (bytes_key + sizeof(struct property_field)) +
			 (bytes_val + sizeof(struct property_field)) +
			 sizeof(struct property_header);
	}

	return bytes;
}

/**
 * Serializes an Android property cache into a buffer recognized by Android
 * This is a well known format described in protobuf here:
 * https://android.googlesource.com/platform/system/core/+/master/init/persistent_properties.proto
 *
 * @cache: a valid android property cache
 * @count: the amount of items in the cache
 * @buf_location: the buffer's address, allocated by the caller
 *
 * @return: the amount of bytes the buffer uses in memory
 */
loff_t aprop_serialize_to_buf(struct android_property *cache, int count,
			      unsigned long buf_location)
{
	struct property_header *hdr;
	struct property_field *field;
	loff_t bytes = 0;

	for (int i = 0; i < count; i++) {
		hdr = (struct property_header *)buf_location;
		hdr->magic = WIRE_TYPE_MULTIPLE;
		hdr->size = 0;

		field = (struct property_field *)hdr->data;
		field->hdr.magic = WIRE_TYPE_MULTIPLE;
		field->hdr.size = strlen(aprop.cache[i].key);
		strncpy(field->string, aprop.cache[i].key, field->hdr.size);
		hdr->size += field->hdr.size + sizeof(struct property_field);

		field = (struct property_field *)(field->string +
						  field->hdr.size);
		field->hdr.magic = WIRE_TYPE_LENGTH_DELIMITED;
		field->hdr.size = strlen(aprop.cache[i].val);
		strncpy(field->string, aprop.cache[i].val, field->hdr.size);
		hdr->size += field->hdr.size + sizeof(struct property_field);

		bytes += hdr->size + sizeof(*hdr);
		buf_location += hdr->size + sizeof(*hdr);
	}

	return bytes;
}

static int aprop_find(const char *const key)
{
	int i;

	for (i = 0; i < aprop.count; i++)
		if (!strncmp(key, aprop.cache[i].key, PROPERTY_MAX_SIZE))
			return i;

	return -1;
}

static int do_aprop_load(cmd_tbl_t *cmdtp, int flag, int argc,
			 char *const argv[])
{
	struct blk_desc *desc;
	disk_partition_t info;
	loff_t filesize;
	loff_t actread;
	char *endp;
	int part, ret;

	ret = blk_get_device_by_str("mmc", argv[1], &desc);
	if (ret < 0) {
		printf("Error: mmc %s:%s read failed (%d)\n", argv[1], argv[2],
		       ret);
		goto err;
	}

	aprop.mmc_dev = desc->devnum;

	part = simple_strtoul(argv[2], &endp, 0);
	if (*endp == '\0') {
		ret = part_get_info(desc, part, &info);
		if (ret) {
			printf("Error: mmc %s:%s read failed (%d)\n", argv[1],
			       argv[2], ret);
			goto err;
		}
	} else {
		part = part_get_info_by_name(desc, argv[2], &info);
		if (part < 0) {
			printf("Error: mmc %s:%s read failed (%d)\n", argv[1],
			       argv[2], ret);
			ret = part;
			goto err;
		}
	}
	aprop.mmc_part = part;

	fs_set_blk_dev_with_part(desc, part);
	ret = fs_size(PERSIST_FILE, &filesize);
	if (ret < 0) {
		printf("Error: getsize %s failed(%d)\n", PERSIST_FILE, ret);
		goto err;
	}

	unsigned long buf_location = (unsigned long)malloc(filesize);
	if (!buf_location) {
		printf("Error: malloc to load %s failed\n", PERSIST_FILE);
		ret = -ENOMEM;
		goto err;
	}

	fs_set_blk_dev_with_part(desc, part);
	ret = fs_read(PERSIST_FILE, buf_location, 0, filesize, &actread);
	if (ret < 0) {
		printf("Error: file %s read failed (%d)\n", PERSIST_FILE, ret);
		goto err_free_filebuf;
	}

	filesize = actread;

	aprop.count = aprop_count_from_buf(buf_location, filesize);
	aprop.cache = malloc(sizeof(struct android_property) * aprop.count);
	if (!aprop.cache) {
		printf("Error: allocate memory to store aprop cache failed\n");
		ret = -ENOMEM;
		goto err_free_filebuf;
	}

	aprop_deserialize_buf(buf_location, aprop.count, aprop.cache);
	free((void *)buf_location);

	debug("%s: Loaded from mmc %d:%d\n", __func__, aprop.mmc_dev,
	      aprop.mmc_part);

	return CMD_RET_SUCCESS;

err_free_filebuf:
	free((void *)buf_location);
err:
	aprop.mmc_dev = -1;
	aprop.mmc_part = -1;
	aprop.count = -1;
	aprop.cache = NULL;

	return CMD_RET_FAILURE;
}

static int do_aprop_get(cmd_tbl_t *cmdtp, int flag, int argc,
			char *const argv[])
{
	int index;
	const char *const requested_key = argv[1];

	index = aprop_find(requested_key);
	if (index < 0) {
		printf("Error: could not find property %s\n", requested_key);
		return CMD_RET_FAILURE;
	}

	printf("%s\n", aprop.cache[index].val);
	return CMD_RET_SUCCESS;
}

static int do_aprop_set(cmd_tbl_t *cmdtp, int flag, int argc,
			char *const argv[])
{
	size_t requested_val_len;
	int index;

	index = aprop_find(argv[1]);
	if (index < 0) {
		printf("Error: could not find property %s\n", argv[1]);
		return CMD_RET_FAILURE;
	}

	requested_val_len = strnlen(argv[2], PROPERTY_MAX_SIZE);
	if (requested_val_len == PROPERTY_MAX_SIZE) {
		printf("Warning: %s is too long, will truncate to %u chars\n",
		       argv[2], PROPERTY_MAX_SIZE);
	}

	strncpy(aprop.cache[index].val, argv[2], requested_val_len);
	aprop.cache[index].val[requested_val_len] = '\0';

	return CMD_RET_SUCCESS;
}

static int do_aprop_test(cmd_tbl_t *cmdtp, int flag, int argc,
			 char *const argv[])
{
	const char *const op = argv[2];
	size_t size;
	int index;

	index = aprop_find(argv[1]);
	if (index == -1) {
		printf("Error: could not find property %s\n", argv[1]);
		return CMD_RET_FAILURE;
	}

	size = strnlen(aprop.cache[index].val, PROPERTY_MAX_SIZE);

	if (*op == '=' && *(op + 1) == '\0') {
		if (!strncmp(aprop.cache[index].val, argv[3], size))
			return CMD_RET_SUCCESS;
		else
			return CMD_RET_FAILURE;
	} else if (*op == '~' && *(op + 1) == '\0') {
		if (!strstr(aprop.cache[index].val, argv[3]))
			return CMD_RET_FAILURE;
		else
			return CMD_RET_SUCCESS;
	} else {
		printf("Error: Unknown operator '%s'\n", op);
	}

	return CMD_RET_FAILURE;
}

static int do_aprop_dump(cmd_tbl_t *cmdtp, int flag, int argc,
			 char *const argv[])
{
	for (int i = 0; i < aprop.count; i++) {
		printf("%s=%s\n", aprop.cache[i].key, aprop.cache[i].val);
	}

	return CMD_RET_SUCCESS;
}

static int do_aprop_store(cmd_tbl_t *cmdtp, int flag, int argc,
			  char *const argv[])
{
	struct blk_desc *desc;
	disk_partition_t info;
	loff_t actwrite;
	loff_t bufsize;
	int ret;
	int cmd_ret = CMD_RET_FAILURE;

	desc = blk_get_devnum_by_type(IF_TYPE_MMC, aprop.mmc_dev);
	if (!desc) {
		printf("Error: mmc %d:%d write failed\n", aprop.mmc_dev,
		       aprop.mmc_part);
		ret = -ENODEV;
		goto end;
	}

	ret = part_get_info(desc, aprop.mmc_part, &info);
	if (ret < 0) {
		printf("Error: mmc %d:%d write failed (%d)\n", aprop.mmc_dev,
		       aprop.mmc_part, ret);
		goto end;
	}

	bufsize = aprop_bufsize_for_cache(aprop.cache, aprop.count);
	unsigned long buf_location = (unsigned long)malloc(bufsize);
	if (!buf_location) {
		printf("Error: malloc to store %s failed (bytes=%llu)\n",
		       PERSIST_FILE, bufsize);
		ret = -ENOMEM;
		goto end;
	}

	aprop_serialize_to_buf(aprop.cache, aprop.count, buf_location);

	fs_set_blk_dev_with_part(desc, aprop.mmc_part);
	ret = fs_write(PERSIST_FILE, buf_location, 0, bufsize, &actwrite);
	if (ret < 0) {
		printf("Error: file %s write failed (%d) bytes=%llu\n",
		       PERSIST_FILE, ret, actwrite);
		goto end_free_filebuf;
	}

	cmd_ret = CMD_RET_SUCCESS;

end_free_filebuf:
	free((void *)buf_location);
end:
	return cmd_ret;
}

static cmd_tbl_t cmd_aprop_sub[] = {
	U_BOOT_CMD_MKENT(load, CONFIG_SYS_MAXARGS, 1, do_aprop_load, "", ""),
	U_BOOT_CMD_MKENT(get, CONFIG_SYS_MAXARGS, 1, do_aprop_get, "", ""),
	U_BOOT_CMD_MKENT(set, CONFIG_SYS_MAXARGS, 1, do_aprop_set, "", ""),
	U_BOOT_CMD_MKENT(test, CONFIG_SYS_MAXARGS, 1, do_aprop_test, "", ""),
	U_BOOT_CMD_MKENT(dump, CONFIG_SYS_MAXARGS, 1, do_aprop_dump, "", ""),
	U_BOOT_CMD_MKENT(store, CONFIG_SYS_MAXARGS, 1, do_aprop_store, "", ""),
};

static int do_aprop(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	cmd_tbl_t *c;

	if (argc < 2)
		return CMD_RET_USAGE;

	argc--;
	argv++;

	c = find_cmd_tbl(argv[0], cmd_aprop_sub, ARRAY_SIZE(cmd_aprop_sub));
	if (!c)
		return CMD_RET_USAGE;

	if (aprop_is_misused(argc, argv)) {
		/*
		 * We try to improve the user experience by reporting the
		 * root-cause of misusage, so don't return CMD_RET_USAGE,
		 * since the latter prints out the full-blown help text
		 */
		return CMD_RET_FAILURE;
	}

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

U_BOOT_CMD(
	aprop, CONFIG_SYS_MAXARGS, 1, do_aprop,
	"Load/get/set/test/dump/store Android persistent properties",
	"load  <dev> <part>     - load properties from mmc <dev>:<part>\n"
	"aprop get   <key>            - retrieves the <val> for <key>\n"
	"aprop set   <key> <val>      - sets <key> to <val>\n"
	"aprop test  <key> <op> <val> - test <key> agains <val>\n"
	"aprop dump                   - dump all properties in <key>=<val> format\n"
	"aprop store                  - store all properties back to mmc\n"
	"Legend:\n"
	"<dev>   - MMC device index containing the aprop partition\n"
	"<part>  - MMC partition index or name containing the property file\n"
	"<key>   - string/text representing a property key\n"
	"<val>   - string/text representing a property value\n"
	"<op>    - the binary operator used in 'aprop test':\n"
	"          '=' returns true if <val> matches <key>'s value\n"
	"          '~' returns true if <val> matches a subset of <key>'s value\n");
