/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later */

#include <assert.h>
#include <commonlib/bsd/cbfs_private.h>
#include <commonlib/bsd/helpers.h>

/*
 * A CBFS metadata cache is an in memory data structure storing CBFS file headers (= metadata).
 * It is defined by its start pointer and size. It contains a sequence of variable-length
 * union mcache_entry entries. There is no overall header structure for the cache.
 *
 * Each mcache_entry is the raw metadata for a CBFS file (including attributes) in the same form
 * as stored on flash (i.e. values in big-endian), except that the CBFS magic signature in the
 * first 8 bytes ('LARCHIVE') is overwritten with mcache-internal bookkeeping data. The first 4
 * bytes are a magic number (MCACHE_MAGIC_FILE) and the next 4 bytes are the absolute offset in
 * bytes on the cbfs_dev_t that this metadata blob was found at. (Note that depending on the
 * implementation of cbfs_dev_t, this offset may still be relative to the start of a subregion
 * of the underlying storage device.)
 *
 * The length of an mcache_entry (i.e. length of the underlying metadata blob) is encoded in the
 * metadata (entry->file.h.offset). The next mcache_entry begins at the next
 * CBFS_MCACHE_ALIGNMENT boundary after that. The cache is terminated by a special 4-byte
 * mcache_entry that consists only of a magic number (MCACHE_MAGIC_END or MCACHE_MAGIC_FULL).
 */

#define MCACHE_MAGIC_FILE	0x454c4946	/* 'FILE' */
#define MCACHE_MAGIC_FULL	0x4c4c5546	/* 'FULL' */
#define MCACHE_MAGIC_END	0x444e4524	/* '$END' */

union mcache_entry {
	union cbfs_mdata file;
	struct {	/* These fields exactly overlap file.h.magic */
		uint32_t magic;
		uint32_t offset;
	};
};

struct cbfs_mcache_build_args {
	void *mcache;
	void *end;
	int count;
};

static enum cb_err build_walker(cbfs_dev_t dev, size_t offset, const union cbfs_mdata *mdata,
				size_t already_read, void *arg)
{
	struct cbfs_mcache_build_args *args = arg;
	union mcache_entry *entry = args->mcache;
	const uint32_t data_offset = be32toh(mdata->h.offset);

	if (args->end - args->mcache < data_offset)
		return CB_CBFS_CACHE_FULL;

	if (cbfs_copy_fill_metadata(args->mcache, mdata, already_read, dev, offset))
		return CB_CBFS_IO;

	entry->magic = MCACHE_MAGIC_FILE;
	entry->offset = offset;

	args->mcache += ALIGN_UP(data_offset, CBFS_MCACHE_ALIGNMENT);
	args->count++;

	return CB_CBFS_NOT_FOUND;
}

enum cb_err cbfs_mcache_build(cbfs_dev_t dev, void *mcache, size_t size,
			      struct vb2_hash *metadata_hash)
{
	struct cbfs_mcache_build_args args = {
		.mcache = mcache,
		.end = mcache + ALIGN_DOWN(size, CBFS_MCACHE_ALIGNMENT)
		       - sizeof(uint32_t), /* leave space for terminating magic */
		.count = 0,
	};

	assert(size > sizeof(uint32_t) && IS_ALIGNED((uintptr_t)mcache, CBFS_MCACHE_ALIGNMENT));
	enum cb_err ret = cbfs_walk(dev, build_walker, &args, metadata_hash, 0);
	union mcache_entry *entry = args.mcache;
	if (ret == CB_CBFS_NOT_FOUND) {
		ret = CB_SUCCESS;
		entry->magic = MCACHE_MAGIC_END;
	} else if (ret == CB_CBFS_CACHE_FULL) {
		ERROR("mcache overflow, should increase CBFS_MCACHE size!\n");
		entry->magic = MCACHE_MAGIC_FULL;
	}

	LOG("mcache @%p built for %d files, used %#zx of %#zx bytes\n", mcache,
	    args.count, args.mcache + sizeof(entry->magic) - mcache, size);
	return ret;
}

enum cb_err cbfs_mcache_lookup(const void *mcache, size_t mcache_size, const char *name,
			       union cbfs_mdata *mdata_out, size_t *data_offset_out)
{
	const size_t namesize = strlen(name) + 1; /* Count trailing \0 so we can memcmp() it. */
	const void *end = mcache + mcache_size;
	const void *current = mcache;

	while (current + sizeof(uint32_t) <= end) {
		const union mcache_entry *entry = current;

		if (entry->magic == MCACHE_MAGIC_END)
			return CB_CBFS_NOT_FOUND;
		if (entry->magic == MCACHE_MAGIC_FULL)
			return CB_CBFS_CACHE_FULL;

		assert(entry->magic == MCACHE_MAGIC_FILE);
		const uint32_t data_offset = be32toh(entry->file.h.offset);
		const uint32_t data_length = be32toh(entry->file.h.len);
		if (namesize <= data_offset - offsetof(union cbfs_mdata, h.filename) &&
		    memcmp(name, entry->file.h.filename, namesize) == 0) {
			LOG("Found '%s' @%#x size %#x in mcache @%p\n",
			    name, entry->offset, data_length, current);
			*data_offset_out = entry->offset + data_offset;
			memcpy(mdata_out, &entry->file, data_offset);
			return CB_SUCCESS;
		}

		current += ALIGN_UP(data_offset, CBFS_MCACHE_ALIGNMENT);
	}

	ERROR("CBFS mcache is not terminated!\n");	/* should never happen */
	return CB_ERR;
}

size_t cbfs_mcache_real_size(const void *mcache, size_t mcache_size)
{
	const void *end = mcache + mcache_size;
	const void *current = mcache;

	while (current + sizeof(uint32_t) <= end) {
		const union mcache_entry *entry = current;

		if (entry->magic == MCACHE_MAGIC_FULL || entry->magic == MCACHE_MAGIC_END) {
			current += sizeof(entry->magic);
			break;
		}

		assert(entry->magic == MCACHE_MAGIC_FILE);
		current += ALIGN_UP(be32toh(entry->file.h.offset), CBFS_MCACHE_ALIGNMENT);
	}

	return current - mcache;
}
