/*
 * Copyright (c) 2023 Yonatan Schachter
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/bindesc.h>
#include <zephyr/sys/util.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/flash.h>

LOG_MODULE_REGISTER(bindesc_read, CONFIG_BINDESC_READ_LOG_LEVEL);

struct find_user_data {
	const void *result;
	size_t size;
	uint16_t tag;
};

/**
 * A callback used by the bindesc_find_* functions.
 */
static int find_callback(const struct bindesc_entry *entry, void *user_data)
{
	struct find_user_data *data = (struct find_user_data *)user_data;

	if (data->tag == entry->tag) {
		data->result = (const void *)&(entry->data);
		data->size = entry->len;
		return 1;
	}

	return 0;
}

/**
 * A callback used by the bindesc_get_size function.
 */
static int get_size_callback(const struct bindesc_entry *entry, void *user_data)
{
	size_t *result = (size_t *)user_data;

	*result += WB_UP(BINDESC_ENTRY_HEADER_SIZE + entry->len);

	return 0;
}

/**
 * This helper function is used to abstract the different methods of reading
 * data from the binary descriptors.
 * For RAM and memory mapped flash, the implementation is very simple, as both
 * are memory mapped and can simply return a pointer to the data.
 * Flash is more complex because it needs to read the data from flash, and do
 * error checking.
 */
static inline int get_entry(struct bindesc_handle *handle, const uint8_t *address,
			    const struct bindesc_entry **entry)
{
	int retval = 0;

	/*
	 * The flash backend requires reading data into a buffer and uses struct
	 * members (flash_device, buffer) that only exist when CONFIG_BINDESC_READ_FLASH
	 * is enabled. We must use preprocessor conditionals here, not IS_ENABLED()
	 * in an if statement, because the compiler still type-checks code in both
	 * branches even when the condition is known false at compile time.
	 */
#if IS_ENABLED(CONFIG_BINDESC_READ_FLASH)
	if (handle->type == BINDESC_HANDLE_TYPE_FLASH) {
		int flash_retval;

		flash_retval = flash_read(handle->flash_device, (size_t)address,
					  handle->buffer, BINDESC_ENTRY_HEADER_SIZE);
		if (flash_retval) {
			LOG_ERR("Flash read error: %d", flash_retval);
			return -EIO;
		}

		/* Make sure buffer is large enough for the data */
		if (((const struct bindesc_entry *)handle->buffer)->len + BINDESC_ENTRY_HEADER_SIZE
				> sizeof(handle->buffer)) {
			LOG_WRN("Descriptor too large to copy, skipping");
			retval = -ENOMEM;
		} else {
			flash_retval = flash_read(handle->flash_device,
					(size_t)address + BINDESC_ENTRY_HEADER_SIZE,
					handle->buffer + BINDESC_ENTRY_HEADER_SIZE,
					((const struct bindesc_entry *)handle->buffer)->len);
			if (flash_retval) {
				LOG_ERR("Flash read error: %d", flash_retval);
				return -EIO;
			}
		}
		*entry = (const struct bindesc_entry *)handle->buffer;
	} else
#endif /* CONFIG_BINDESC_READ_FLASH */
	{
		*entry = (const struct bindesc_entry *)address;
	}

	return retval;
}

#if IS_ENABLED(CONFIG_BINDESC_READ_MEMORY_MAPPED_FLASH)
int bindesc_open_memory_mapped_flash(struct bindesc_handle *handle, size_t offset)
{
	uint8_t *address = (uint8_t *)CONFIG_FLASH_BASE_ADDRESS + offset;

	if (*(uint64_t *)address != BINDESC_MAGIC) {
		LOG_ERR("Magic not found in given address");
		return -ENOENT;
	}

	handle->address = address;
	handle->type = BINDESC_HANDLE_TYPE_MEMORY_MAPPED_FLASH;
	handle->size_limit = UINT16_MAX;
	return 0;
}
#endif /* IS_ENABLED(CONFIG_BINDESC_READ_RAM) */

#if IS_ENABLED(CONFIG_BINDESC_READ_RAM)
int bindesc_open_ram(struct bindesc_handle *handle, const uint8_t *address, size_t max_size)
{
	if (!IS_ALIGNED(address, BINDESC_ALIGNMENT)) {
		LOG_ERR("Given address is not aligned");
		return -EINVAL;
	}

	if (*(uint64_t *)address != BINDESC_MAGIC) {
		LOG_ERR("Magic not found in given address");
		return -ENOENT;
	}

	handle->address = address;
	handle->type = BINDESC_HANDLE_TYPE_RAM;
	handle->size_limit = max_size;
	return 0;
}
#endif /* IS_ENABLED(CONFIG_BINDESC_READ_RAM) */

#if IS_ENABLED(CONFIG_BINDESC_READ_FLASH)
int bindesc_open_flash(struct bindesc_handle *handle, size_t offset,
		       const struct device *flash_device)
{
	int retval;

	retval = flash_read(flash_device, offset, handle->buffer, sizeof(BINDESC_MAGIC));
	if (retval) {
		LOG_ERR("Flash read error: %d", retval);
		return -EIO;
	}

	if (*(uint64_t *)handle->buffer != BINDESC_MAGIC) {
		LOG_ERR("Magic not found in given address");
		return -ENOENT;
	}

	handle->address = (uint8_t *)offset;
	handle->type = BINDESC_HANDLE_TYPE_FLASH;
	handle->flash_device = flash_device;
	handle->size_limit = UINT16_MAX;
	return 0;
}
#endif /* IS_ENABLED(CONFIG_BINDESC_READ_FLASH) */

int bindesc_foreach(struct bindesc_handle *handle, bindesc_callback_t callback, void *user_data)
{
	const struct bindesc_entry *entry;
	const uint8_t *address = handle->address;
	int retval;

	address += sizeof(BINDESC_MAGIC);

	do {
		retval = get_entry(handle, address, &entry);
		if (retval == -EIO) {
			return -EIO;
		}
		address += WB_UP(BINDESC_ENTRY_HEADER_SIZE + entry->len);
		if (retval) {
			continue;
		}

		retval = callback(entry, user_data);
		if (retval) {
			return retval;
		}
	} while ((entry->tag != BINDESC_TAG_DESCRIPTORS_END) &&
		((address - handle->address) <= handle->size_limit));

	return 0;
}

int bindesc_find_str(struct bindesc_handle *handle, uint16_t id, const char **result)
{
	struct find_user_data data = {
		.tag = BINDESC_TAG(STR, id),
	};

	if (!bindesc_foreach(handle, find_callback, &data)) {
		LOG_WRN("The requested descriptor was not found");
		return -ENOENT;
	}
	*result = (char *)data.result;
	return 0;
}

int bindesc_find_uint(struct bindesc_handle *handle, uint16_t id, const uint32_t **result)
{
	struct find_user_data data = {
		.tag = BINDESC_TAG(UINT, id),
	};

	if (!bindesc_foreach(handle, find_callback, &data)) {
		LOG_WRN("The requested descriptor was not found");
		return -ENOENT;
	}
	*result = (const uint32_t *)data.result;
	return 0;
}

int bindesc_find_bytes(struct bindesc_handle *handle, uint16_t id, const uint8_t **result,
		       size_t *result_size)
{
	struct find_user_data data = {
		.tag = BINDESC_TAG(BYTES, id),
	};

	if (!bindesc_foreach(handle, find_callback, &data)) {
		LOG_WRN("The requested descriptor was not found");
		return -ENOENT;
	}
	*result = (const uint8_t *)data.result;
	*result_size = data.size;
	return 0;
}

int bindesc_get_size(struct bindesc_handle *handle, size_t *result)
{
	*result = sizeof(BINDESC_MAGIC);

	return bindesc_foreach(handle, get_size_callback, result);
}
