/*
 * 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) {
			uint8_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) {
			uint8_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)
