/*
 * Copyright (c) 2023, Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT zephyr_retention

#include <string.h>
#include <sys/types.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/util.h>
#include <zephyr/sys/crc.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/retained_mem.h>
#include <zephyr/retention/retention.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(retention, CONFIG_RETENTION_LOG_LEVEL);

#define DATA_VALID_VALUE 1

#define INST_HAS_CHECKSUM(n) DT_INST_PROP(n, checksum) ||

#define INST_HAS_PREFIX(n) COND_CODE_1(DT_INST_NODE_HAS_PROP(n, prefix), (1), (0)) ||

#if (DT_INST_FOREACH_STATUS_OKAY(INST_HAS_CHECKSUM) 0)
#define ANY_HAS_CHECKSUM
#endif

#if (DT_INST_FOREACH_STATUS_OKAY(INST_HAS_PREFIX) 0)
#define ANY_HAS_PREFIX
#endif

enum {
	CHECKSUM_NONE = 0,
	CHECKSUM_CRC8,
	CHECKSUM_CRC16,
	CHECKSUM_UNUSED,
	CHECKSUM_CRC32,
};

struct retention_data {
	bool header_written;
#ifdef CONFIG_RETENTION_MUTEXES
	struct k_mutex lock;
#endif
};

struct retention_config {
	const struct device *parent;
	size_t offset;
	size_t size;
	size_t reserved_size;
	uint8_t checksum_size;
	uint8_t prefix_len;
	uint8_t prefix[];
};

static inline void retention_lock_take(const struct device *dev)
{
#ifdef CONFIG_RETENTION_MUTEXES
	struct retention_data *data = dev->data;

	k_mutex_lock(&data->lock, K_FOREVER);
#else
	ARG_UNUSED(dev);
#endif
}

static inline void retention_lock_release(const struct device *dev)
{
#ifdef CONFIG_RETENTION_MUTEXES
	struct retention_data *data = dev->data;

	k_mutex_unlock(&data->lock);
#else
	ARG_UNUSED(dev);
#endif
}

#ifdef ANY_HAS_CHECKSUM
static int retention_checksum(const struct device *dev, uint32_t *output)
{
	const struct retention_config *config = dev->config;
	int rc = -ENOSYS;

	if (config->checksum_size == CHECKSUM_CRC8 ||
	    config->checksum_size == CHECKSUM_CRC16 ||
	    config->checksum_size == CHECKSUM_CRC32) {
		size_t pos = config->offset + config->prefix_len;
		size_t end = config->offset + config->size - config->checksum_size;
		uint8_t buffer[CONFIG_RETENTION_BUFFER_SIZE];

		*output = 0;

		while (pos < end) {
			uint16_t read_size = MIN((end - pos), sizeof(buffer));

			rc = retained_mem_read(config->parent, pos, buffer, read_size);

			if (rc < 0) {
				goto finish;
			}

			if (config->checksum_size == CHECKSUM_CRC8) {
				*output = (uint32_t)crc8(buffer, read_size, 0x12,
							 (uint8_t)*output, false);
			} else if (config->checksum_size == CHECKSUM_CRC16) {
				*output = (uint32_t)crc16_itu_t((uint16_t)*output,
								buffer, read_size);
			} else if (config->checksum_size == CHECKSUM_CRC32) {
				*output = crc32_ieee_update(*output, buffer, read_size);
			}

			pos += read_size;
		}
	}

finish:
	return rc;
}
#endif

static int retention_init(const struct device *dev)
{
	const struct retention_config *config = dev->config;
#ifdef CONFIG_RETENTION_MUTEXES
	struct retention_data *data = dev->data;
#endif
	ssize_t area_size;

	if (!device_is_ready(config->parent)) {
		LOG_ERR("Parent device is not ready");
		return -ENODEV;
	}

	/* Ensure backend has a large enough storage area for the requirements of
	 * this retention area
	 */
	area_size = retained_mem_size(config->parent);

	if (area_size < 0) {
		LOG_ERR("Parent initialisation failure: %d", area_size);
		return area_size;
	}

	if ((config->offset + config->size) > area_size) {
		/* Backend storage is insufficient */
		LOG_ERR("Underlying area size is insufficient, requires: 0x%x, has: 0x%x",
			(config->offset + config->size), area_size);
		return -EINVAL;
	}

#ifdef CONFIG_RETENTION_MUTEXES
	k_mutex_init(&data->lock);
#endif

	return 0;
}

ssize_t retention_size(const struct device *dev)
{
	const struct retention_config *config = dev->config;

	return (config->size - config->reserved_size);
}

int retention_is_valid(const struct device *dev)
{
	const struct retention_config *config = dev->config;
	int rc = 0;

	retention_lock_take(dev);

	/* If neither the header or checksum are enabled, return a not supported error */
	if (config->prefix_len == 0 && config->checksum_size == 0) {
		rc = -ENOTSUP;
		goto finish;
	}

#ifdef ANY_HAS_PREFIX
	if (config->prefix_len != 0) {
		/* Check magic header is present at the start of the section */
		struct retention_data *data = dev->data;
		uint8_t buffer[CONFIG_RETENTION_BUFFER_SIZE];
		off_t pos = 0;

		while (pos < config->prefix_len) {
			uint16_t read_size = MIN((config->prefix_len - pos), sizeof(buffer));

			rc = retained_mem_read(config->parent, (config->offset + pos), buffer,
					       read_size);

			if (rc < 0) {
				goto finish;
			}

			if (memcmp(&config->prefix[pos], buffer, read_size) != 0) {
				/* If the magic header does not match, do not check the rest of
				 * the validity of the data, assume it is invalid
				 */
				data->header_written = false;
				rc = 0;
				goto finish;
			}

			pos += read_size;
		}

		/* Header already exists so no need to re-write it again */
		data->header_written = true;
	}
#endif

#ifdef ANY_HAS_CHECKSUM
	if (config->checksum_size != 0) {
		/* Check the checksum validity, for this all the data must be read out */
		uint32_t checksum = 0;
		uint32_t expected_checksum = 0;
		ssize_t data_size = config->size - config->checksum_size;

		rc = retention_checksum(dev, &checksum);

		if (rc < 0) {
			goto finish;
		}

		if (config->checksum_size == CHECKSUM_CRC8) {
			uint8_t read_checksum;

			rc = retained_mem_read(config->parent, (config->offset + data_size),
					       (void *)&read_checksum, sizeof(read_checksum));
			expected_checksum = (uint32_t)read_checksum;
		} else if (config->checksum_size == CHECKSUM_CRC16) {
			uint16_t read_checksum;

			rc = retained_mem_read(config->parent, (config->offset + data_size),
					       (void *)&read_checksum, sizeof(read_checksum));
			expected_checksum = (uint32_t)read_checksum;
		} else if (config->checksum_size == CHECKSUM_CRC32) {
			rc = retained_mem_read(config->parent, (config->offset + data_size),
					       (void *)&expected_checksum,
					       sizeof(expected_checksum));
		}

		if (rc < 0) {
			goto finish;
		}

		if (checksum != expected_checksum) {
			goto finish;
		}
	}
#endif

	/* At this point, checks have passed (if enabled), mark data as being valid */
	rc = DATA_VALID_VALUE;

finish:
	retention_lock_release(dev);

	return rc;
}

int retention_read(const struct device *dev, off_t offset, uint8_t *buffer, size_t size)
{
	const struct retention_config *config = dev->config;
	int rc;

	if (offset < 0 || ((size_t)offset + size) > (config->size - config->reserved_size)) {
		/* Disallow reading past the virtual data size or before it */
		return -EINVAL;
	}

	retention_lock_take(dev);

	rc = retained_mem_read(config->parent, (config->offset + config->prefix_len +
			       (size_t)offset), buffer, size);

	retention_lock_release(dev);

	return rc;
}

int retention_write(const struct device *dev, off_t offset, const uint8_t *buffer, size_t size)
{
	const struct retention_config *config = dev->config;
	int rc;

#ifdef ANY_HAS_PREFIX
	struct retention_data *data = dev->data;
#endif

	retention_lock_take(dev);

	if (offset < 0 || ((size_t)offset + size) > (config->size - config->reserved_size)) {
		/* Disallow writing past the virtual data size or before it */
		rc = -EINVAL;
		goto finish;
	}

	rc = retained_mem_write(config->parent, (config->offset + config->prefix_len +
				(size_t)offset), buffer, size);

	if (rc < 0) {
		goto finish;
	}

#ifdef ANY_HAS_PREFIX
	/* Write optional header and footer information, these are done last to ensure data
	 * validity before marking it as being valid
	 */
	if (config->prefix_len != 0 && data->header_written == false) {
		rc = retained_mem_write(config->parent, config->offset, (void *)config->prefix,
					config->prefix_len);

		if (rc < 0) {
			goto finish;
		}

		data->header_written = true;
	}
#endif

#ifdef ANY_HAS_CHECKSUM
	if (config->checksum_size != 0) {
		/* Generating a checksum requires reading out all the data in the region */
		uint32_t checksum = 0;

		rc = retention_checksum(dev, &checksum);

		if (rc < 0) {
			goto finish;
		}

		if (config->checksum_size == CHECKSUM_CRC8) {
			uint8_t output_checksum = (uint8_t)checksum;

			rc = retained_mem_write(config->parent,
					(config->offset + config->size - config->checksum_size),
					(void *)&output_checksum, sizeof(output_checksum));
		} else if (config->checksum_size == CHECKSUM_CRC16) {
			uint16_t output_checksum = (uint16_t)checksum;

			rc = retained_mem_write(config->parent,
					(config->offset + config->size - config->checksum_size),
					(void *)&output_checksum, sizeof(output_checksum));
		} else if (config->checksum_size == CHECKSUM_CRC32) {
			rc = retained_mem_write(config->parent,
					(config->offset + config->size - config->checksum_size),
					(void *)&checksum, sizeof(checksum));
		}
	}
#endif

finish:
	retention_lock_release(dev);

	return rc;
}

int retention_clear(const struct device *dev)
{
	const struct retention_config *config = dev->config;
	struct retention_data *data = dev->data;
	int rc = 0;
	uint8_t buffer[CONFIG_RETENTION_BUFFER_SIZE];
	off_t pos = 0;

	memset(buffer, 0, sizeof(buffer));

	retention_lock_take(dev);

	data->header_written = false;

	while (pos < config->size) {
		rc = retained_mem_write(config->parent, (config->offset + pos), buffer,
					MIN((config->size - pos), sizeof(buffer)));

		if (rc < 0) {
			goto finish;
		}

		pos += MIN((config->size - pos), sizeof(buffer));
	}

finish:
	retention_lock_release(dev);

	return rc;
}

static const struct retention_api retention_api = {
	.size = retention_size,
	.is_valid = retention_is_valid,
	.read = retention_read,
	.write = retention_write,
	.clear = retention_clear,
};

#define RETENTION_DEVICE(inst)									\
	static struct retention_data								\
		retention_data_##inst = {							\
		.header_written = false,							\
	};											\
	static const struct retention_config							\
		retention_config_##inst = {							\
		.parent = DEVICE_DT_GET(DT_PARENT(DT_INST(inst, DT_DRV_COMPAT))),		\
		.checksum_size = DT_INST_PROP(inst, checksum),					\
		.offset = DT_INST_REG_ADDR(inst),						\
		.size = DT_INST_REG_SIZE(inst),							\
		.reserved_size = (COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, prefix),		\
					      (DT_INST_PROP_LEN(inst, prefix)), (0)) +		\
				  DT_INST_PROP(inst, checksum)),				\
		.prefix_len = COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, prefix),			\
					  (DT_INST_PROP_LEN(inst, prefix)), (0)),		\
		.prefix = DT_INST_PROP_OR(inst, prefix, {0}),					\
	};											\
	DEVICE_DT_INST_DEFINE(inst,								\
			      &retention_init,							\
			      NULL,								\
			      &retention_data_##inst,						\
			      &retention_config_##inst,						\
			      POST_KERNEL,							\
			      CONFIG_RETENTION_INIT_PRIORITY,					\
			      &retention_api);

DT_INST_FOREACH_STATUS_OKAY(RETENTION_DEVICE)
