/*
 * Copyright (c) 2020 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <zephyr/kernel.h>
#include <string.h>
#include <zephyr/toolchain.h>
#include <zephyr/storage/flash_map.h>
#include <zephyr/storage/stream_flash.h>
#include <zephyr/sys/util.h>

#include <zephyr/debug/coredump.h>
#include "coredump_internal.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(coredump, CONFIG_KERNEL_LOG_LEVEL);

/**
 * @file
 * @brief Simple coredump backend to store data in flash partition.
 *
 * This provides a simple backend to store coredump data in a flash
 * partition, labeled "coredump-partition" in devicetree.
 *
 * On the partition, a header is stored at the beginning with padding
 * at the end to align with flash write size. Then the actual
 * coredump data follows. The padding is to simplify the data read
 * function so that the first read of a data stream is always
 * aligned to flash write size.
 */
#define FLASH_PARTITION		coredump_partition
#define FLASH_PARTITION_ID	FIXED_PARTITION_ID(FLASH_PARTITION)

#if !FIXED_PARTITION_EXISTS(FLASH_PARTITION)
#error "Need a fixed partition named 'coredump-partition'!"

#else

#define FLASH_CONTROLLER	\
	DT_PARENT(DT_PARENT(DT_NODELABEL(FLASH_PARTITION)))

#define FLASH_WRITE_SIZE	DT_PROP(FLASH_CONTROLLER, write_block_size)
#define FLASH_BUF_SIZE		FLASH_WRITE_SIZE
#define FLASH_ERASE_SIZE	DT_PROP(FLASH_CONTROLLER, erase_block_size)

#define HDR_VER			1

#define FLASH_BACKEND_SEM_TIMEOUT (k_is_in_isr() ? K_NO_WAIT : K_FOREVER)

typedef int (*data_read_cb_t)(void *arg, uint8_t *buf, size_t len);

static struct {
	/* For use with flash map */
	const struct flash_area		*flash_area;

	/* For use with streaming flash */
	struct stream_flash_ctx		stream_ctx;

	/* Checksum of data so far */
	uint16_t			checksum;

	/* Error encountered */
	int				error;
} backend_ctx;

/* Buffer used in stream flash context */
static uint8_t stream_flash_buf[FLASH_BUF_SIZE];

/* Buffer used in data_read() */
static uint8_t data_read_buf[FLASH_BUF_SIZE];

/* Semaphore for exclusive flash access */
K_SEM_DEFINE(flash_sem, 1, 1);


struct flash_hdr_t {
	/* 'C', 'D' */
	char		id[2];

	/* Header version */
	uint16_t	hdr_version;

	/* Coredump size, excluding this header */
	size_t		size;

	/* Flags */
	uint16_t	flags;

	/* Checksum */
	uint16_t	checksum;

	/* Error */
	int		error;
} __packed;


/**
 * @brief Open the flash partition.
 *
 * @return Same as flash_area_open().
 */
static int partition_open(void)
{
	int ret;

	(void)k_sem_take(&flash_sem, FLASH_BACKEND_SEM_TIMEOUT);

	ret = flash_area_open(FLASH_PARTITION_ID, &backend_ctx.flash_area);
	if (ret != 0) {
		LOG_ERR("Error opening flash partition for coredump!");

		backend_ctx.flash_area = NULL;
		k_sem_give(&flash_sem);
	}

	return ret;
}

/**
 * @brief Close the flash partition.
 */
static void partition_close(void)
{
	if (backend_ctx.flash_area == NULL) {
		return;
	}

	flash_area_close(backend_ctx.flash_area);
	backend_ctx.flash_area = NULL;

	k_sem_give(&flash_sem);
}

/**
 * @brief Read data from flash partition.
 *
 * This reads @p len bytes in the flash partition starting
 * from @p off and put into buffer pointed by @p dst if
 * @p dst is not NULL.
 *
 * If @p cb is not NULL, data being read are passed to
 * the callback for processing. Note that the data being
 * passed to callback may only be part of the data requested.
 * The end of read is signaled to the callback with NULL
 * buffer pointer and zero length as arguments.
 *
 * @param off offset of partition to begin reading
 * @param dst buffer to read data into (can be NULL)
 * @param len number of bytes to read
 * @param cb callback to process read data (can be NULL)
 * @param cb_arg argument passed to callback
 * @return 0 if successful, error otherwise.
 */
static int data_read(off_t off, uint8_t *dst, size_t len,
		     data_read_cb_t cb, void *cb_arg)
{
	int ret = 0;
	off_t offset = off;
	size_t remaining = len;
	size_t copy_sz;
	uint8_t *ptr = dst;

	if (backend_ctx.flash_area == NULL) {
		return -ENODEV;
	}

	copy_sz = FLASH_BUF_SIZE;
	while (remaining > 0) {
		if (remaining < FLASH_BUF_SIZE) {
			copy_sz = remaining;
		}

		ret = flash_area_read(backend_ctx.flash_area, offset,
				      data_read_buf, FLASH_BUF_SIZE);
		if (ret != 0) {
			break;
		}

		if (dst != NULL) {
			(void)memcpy(ptr, data_read_buf, copy_sz);
		}

		if (cb != NULL) {
			ret = (*cb)(cb_arg, data_read_buf, copy_sz);
			if (ret != 0) {
				break;
			}
		}

		ptr += copy_sz;
		offset += copy_sz;
		remaining -= copy_sz;
	}

	if (cb != NULL) {
		ret = (*cb)(cb_arg, NULL, 0);
	}

	return ret;
}

/**
 * @brief Callback to calculate checksum.
 *
 * @param arg callback argument (not being used)
 * @param buf data buffer
 * @param len number of bytes in buffer to process
 * @return 0
 */
static int cb_calc_buf_checksum(void *arg, uint8_t *buf, size_t len)
{
	int i;

	ARG_UNUSED(arg);

	for (i = 0; i < len; i++) {
		backend_ctx.checksum += buf[i];
	}

	return 0;
}

/**
 * @brief Process the stored coredump in flash partition.
 *
 * This reads the stored coredump data and processes it via
 * the callback function.
 *
 * @param cb callback to process the stored coredump data
 * @param cb_arg argument passed to callback
 * @return 1 if successful; 0 if stored coredump is not found
 *         or is not valid; error otherwise
 */
static int process_stored_dump(data_read_cb_t cb, void *cb_arg)
{
	int ret;
	struct flash_hdr_t hdr;
	off_t offset;

	ret = partition_open();
	if (ret != 0) {
		goto out;
	}

	/* Read header */
	ret = data_read(0, (uint8_t *)&hdr, sizeof(hdr), NULL, NULL);

	/* Verify header signature */
	if ((hdr.id[0] != 'C') && (hdr.id[1] != 'D')) {
		ret = 0;
		goto out;
	}

	/* Error encountered while dumping, so non-existent */
	if (hdr.error != 0) {
		ret = 0;
		goto out;
	}

	backend_ctx.checksum = 0;

	offset = ROUND_UP(sizeof(struct flash_hdr_t), FLASH_WRITE_SIZE);
	ret = data_read(offset, NULL, hdr.size, cb, cb_arg);

	if (ret == 0) {
		ret = (backend_ctx.checksum == hdr.checksum) ? 1 : 0;
	}

out:
	partition_close();

	return ret;
}

/**
 * @brief Get the stored coredump in flash partition.
 *
 * This reads the stored coredump data and copies the raw data
 * to the destination buffer.
 *
 * If the destination buffer is NULL, the offset and length are
 * ignored and the entire dump size is returned.
 *
 * @param off offset of partition to begin reading
 * @param dst buffer to read data into (can be NULL)
 * @param len number of bytes to read
 * @return dump size if successful; 0 if stored coredump is not found
 *         or is not valid; error otherwise
 */
static int get_stored_dump(off_t off, uint8_t *dst, size_t len)
{
	int ret;
	struct flash_hdr_t hdr;

	ret = partition_open();
	if (ret != 0) {
		goto out;
	}

	/* Read header */
	ret = data_read(0, (uint8_t *)&hdr, sizeof(hdr), NULL, NULL);
	if (ret != 0) {
		goto out;
	}

	/* Verify header signature */
	if ((hdr.id[0] != 'C') && (hdr.id[1] != 'D')) {
		ret = 0;
		goto out;
	}

	/* Error encountered while dumping, so non-existent */
	if (hdr.error != 0) {
		ret = 0;
		goto out;
	}

	/* Return the dump size if no destination buffer available */
	if (!dst) {
		ret = (int)hdr.size;
		goto out;
	}

	/* Offset larger than dump size */
	if (off >= hdr.size) {
		ret = 0;
		goto out;
	}

	/* Start reading the data, skip write-aligned header */
	off += ROUND_UP(sizeof(struct flash_hdr_t), FLASH_WRITE_SIZE);

	ret = data_read(off, dst, len, NULL, NULL);
	if (ret == 0) {
		ret = (int)len;
	}
out:
	partition_close();

	return ret;
}

/**
 * @brief Erase the stored coredump header from flash partition.
 *
 * This erases the stored coredump header from the flash partition,
 * invalidating the coredump data.
 *
 * @return 0 if successful; error otherwise
 */
static int erase_coredump_header(void)
{
	int ret;

	ret = partition_open();
	if (ret == 0) {
		/* Erase header block */
		ret = flash_area_erase(backend_ctx.flash_area, 0,
				       ROUND_UP(sizeof(struct flash_hdr_t),
						FLASH_ERASE_SIZE));
	}

	partition_close();

	return ret;
}

/**
 * @brief Erase the stored coredump in flash partition.
 *
 * This erases the stored coredump data from the flash partition.
 *
 * @return 0 if successful; error otherwise
 */
static int erase_flash_partition(void)
{
	int ret;

	ret = partition_open();
	if (ret == 0) {
		/* Erase whole flash partition */
		ret = flash_area_erase(backend_ctx.flash_area, 0,
				       backend_ctx.flash_area->fa_size);
	}

	partition_close();

	return ret;
}

/**
 * @brief Start of coredump session.
 *
 * This opens the flash partition for processing.
 */
static void coredump_flash_backend_start(void)
{
	const struct device *flash_dev;
	size_t offset, header_size;
	int ret;

	ret = partition_open();

	if (ret == 0) {
		/* Erase whole flash partition */
		ret = flash_area_erase(backend_ctx.flash_area, 0,
				       backend_ctx.flash_area->fa_size);
	}

	if (ret == 0) {
		backend_ctx.checksum = 0;

		flash_dev = flash_area_get_device(backend_ctx.flash_area);

		/*
		 * Reserve space for header from beginning of flash device.
		 * The header size is rounded up so the beginning of coredump
		 * is aligned to write size (for easier read and seek).
		 */
		header_size = ROUND_UP(sizeof(struct flash_hdr_t), FLASH_WRITE_SIZE);
		offset = backend_ctx.flash_area->fa_off + header_size;

		ret = stream_flash_init(&backend_ctx.stream_ctx, flash_dev,
					stream_flash_buf,
					sizeof(stream_flash_buf),
					offset,
					backend_ctx.flash_area->fa_size - header_size,
					NULL);
	}

	if (ret != 0) {
		LOG_ERR("Cannot start coredump!");
		backend_ctx.error = ret;
		partition_close();
	}
}

/**
 * @brief End of coredump session.
 *
 * This ends the coredump session by flushing coredump data
 * flash, and writes the header in the beginning of flash
 * related to the stored coredump data.
 */
static void coredump_flash_backend_end(void)
{
	int ret;

	struct flash_hdr_t hdr = {
		.id = {'C', 'D'},
		.hdr_version = HDR_VER,
	};

	if (backend_ctx.flash_area == NULL) {
		return;
	}

	/* Flush buffer */
	backend_ctx.error = stream_flash_buffered_write(
				&backend_ctx.stream_ctx,
				stream_flash_buf, 0, true);

	/* Write header */
	hdr.size = stream_flash_bytes_written(&backend_ctx.stream_ctx);
	hdr.checksum = backend_ctx.checksum;
	hdr.error = backend_ctx.error;
	hdr.flags = 0;

	ret = flash_area_write(backend_ctx.flash_area, 0, (void *)&hdr, sizeof(hdr));
	if (ret != 0) {
		LOG_ERR("Cannot write coredump header!");
		backend_ctx.error = ret;
	}

	if (backend_ctx.error != 0) {
		LOG_ERR("Error in coredump backend (%d)!",
			backend_ctx.error);
	}

	partition_close();
}

/**
 * @brief Write a buffer to flash partition.
 *
 * This writes @p buf into the flash partition. Note that this is
 * using the stream flash interface, so there is no need to keep
 * track of where on flash to write next.
 *
 * @param buf buffer of data to write to flash
 * @param buflen number of bytes to write
 */
static void coredump_flash_backend_buffer_output(uint8_t *buf, size_t buflen)
{
	int i;
	size_t remaining = buflen;
	size_t copy_sz;
	uint8_t *ptr = buf;
	uint8_t tmp_buf[FLASH_BUF_SIZE];

	if ((backend_ctx.error != 0) || (backend_ctx.flash_area == NULL)) {
		return;
	}

	/*
	 * Since the system is still running, memory content is constantly
	 * changing (e.g. stack of this thread). We need to make a copy of
	 * part of the buffer, so that the checksum corresponds to what is
	 * being written.
	 */
	copy_sz = FLASH_BUF_SIZE;
	while (remaining > 0) {
		if (remaining < FLASH_BUF_SIZE) {
			copy_sz = remaining;
		}

		(void)memcpy(tmp_buf, ptr, copy_sz);

		for (i = 0; i < copy_sz; i++) {
			backend_ctx.checksum += tmp_buf[i];
		}

		backend_ctx.error = stream_flash_buffered_write(
					&backend_ctx.stream_ctx,
					tmp_buf, copy_sz, false);
		if (backend_ctx.error != 0) {
			LOG_ERR("Flash write error: %d", backend_ctx.error);
			break;
		}

		ptr += copy_sz;
		remaining -= copy_sz;
	}
}

/**
 * @brief Perform query on this backend.
 *
 * @param query_id ID of query
 * @param arg argument of query
 * @return depends on query
 */
static int coredump_flash_backend_query(enum coredump_query_id query_id,
					void *arg)
{
	int ret;

	switch (query_id) {
	case COREDUMP_QUERY_GET_ERROR:
		ret = backend_ctx.error;
		break;
	case COREDUMP_QUERY_HAS_STORED_DUMP:
		ret = process_stored_dump(cb_calc_buf_checksum, NULL);
		break;
	case COREDUMP_QUERY_GET_STORED_DUMP_SIZE:
		ret = get_stored_dump(0, NULL, 0);
		break;
	default:
		ret = -ENOTSUP;
		break;
	}

	return ret;
}

/**
 * @brief Perform command on this backend.
 *
 * @param cmd_id command ID
 * @param arg argument of command
 * @return depends on query
 */
static int coredump_flash_backend_cmd(enum coredump_cmd_id cmd_id,
				      void *arg)
{
	int ret;

	switch (cmd_id) {
	case COREDUMP_CMD_CLEAR_ERROR:
		ret = 0;
		backend_ctx.error = 0;
		break;
	case COREDUMP_CMD_VERIFY_STORED_DUMP:
		ret = process_stored_dump(cb_calc_buf_checksum, NULL);
		break;
	case COREDUMP_CMD_ERASE_STORED_DUMP:
		ret = erase_flash_partition();
		break;
	case COREDUMP_CMD_COPY_STORED_DUMP:
		if (arg) {
			struct coredump_cmd_copy_arg *copy_arg
				= (struct coredump_cmd_copy_arg *)arg;

			ret = get_stored_dump(copy_arg->offset,
					      copy_arg->buffer,
					      copy_arg->length);
		} else {
			ret = -EINVAL;
		}
		break;
	case COREDUMP_CMD_INVALIDATE_STORED_DUMP:
		ret = erase_coredump_header();
		break;
	default:
		ret = -ENOTSUP;
		break;
	}

	return ret;
}


struct coredump_backend_api coredump_backend_flash_partition = {
	.start = coredump_flash_backend_start,
	.end = coredump_flash_backend_end,
	.buffer_output = coredump_flash_backend_buffer_output,
	.query = coredump_flash_backend_query,
	.cmd = coredump_flash_backend_cmd,
};

#ifdef CONFIG_DEBUG_COREDUMP_SHELL
#include <zephyr/shell/shell.h>

/* Length of buffer of printable size */
#define PRINT_BUF_SZ		64

/* Length of buffer of printable size plus null character */
#define PRINT_BUF_SZ_RAW	(PRINT_BUF_SZ + 1)

/* Print buffer */
static char print_buf[PRINT_BUF_SZ_RAW];
static off_t print_buf_ptr;

/**
 * @brief Shell command to get backend error.
 *
 * @param sh shell instance
 * @param argc (not used)
 * @param argv (not used)
 * @return 0
 */
static int cmd_coredump_error_get(const struct shell *sh,
				  size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (backend_ctx.error == 0) {
		shell_print(sh, "No error.");
	} else {
		shell_print(sh, "Error: %d", backend_ctx.error);
	}

	return 0;
}

/**
 * @brief Shell command to clear backend error.
 *
 * @param sh shell instance
 * @param argc (not used)
 * @param argv (not used)
 * @return 0
 */
static int cmd_coredump_error_clear(const struct shell *sh,
				    size_t argc, char **argv)
{
	backend_ctx.error = 0;

	shell_print(sh, "Error cleared.");

	return 0;
}

/**
 * @brief Shell command to see if there is a stored coredump in flash.
 *
 * @param sh shell instance
 * @param argc (not used)
 * @param argv (not used)
 * @return 0
 */
static int cmd_coredump_has_stored_dump(const struct shell *sh,
					size_t argc, char **argv)
{
	int ret;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	ret = coredump_flash_backend_query(COREDUMP_QUERY_HAS_STORED_DUMP,
					   NULL);

	if (ret == 1) {
		shell_print(sh, "Stored coredump found.");
	} else if (ret == 0) {
		shell_print(sh, "Stored coredump NOT found.");
	} else {
		shell_print(sh, "Failed to perform query: %d", ret);
	}

	return 0;
}

/**
 * @brief Shell command to verify if the stored coredump is valid.
 *
 * @param sh shell instance
 * @param argc (not used)
 * @param argv (not used)
 * @return 0
 */
static int cmd_coredump_verify_stored_dump(const struct shell *sh,
					   size_t argc, char **argv)
{
	int ret;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	ret = coredump_flash_backend_cmd(COREDUMP_CMD_VERIFY_STORED_DUMP,
					 NULL);

	if (ret == 1) {
		shell_print(sh, "Stored coredump verified.");
	} else if (ret == 0) {
		shell_print(sh, "Stored coredump verification failed "
				   "or there is no stored coredump.");
	} else {
		shell_print(sh, "Failed to perform verify command: %d",
			    ret);
	}

	return 0;
}

/**
 * @brief Flush the print buffer to shell.
 *
 * This prints what is in the print buffer to the shell.
 *
 * @param sh shell instance.
 */
static void flush_print_buf(const struct shell *sh)
{
	shell_print(sh, "%s%s", COREDUMP_PREFIX_STR, print_buf);
	print_buf_ptr = 0;
	(void)memset(print_buf, 0, sizeof(print_buf));
}

/**
 * @brief Callback to print stored coredump to shell
 *
 * This converts the binary data in @p buf to hexadecimal digits
 * which can be printed to the shell.
 *
 * @param arg shell instance
 * @param buf binary data buffer
 * @param len number of bytes in buffer to be printed
 * @return 0 if no issues; -EINVAL if error converting data
 */
static int cb_print_stored_dump(void *arg, uint8_t *buf, size_t len)
{
	int ret = 0;
	size_t i = 0;
	size_t remaining = len;
	const struct shell *sh = (const struct shell *)arg;

	if (len == 0) {
		/* Flush print buffer */
		flush_print_buf(sh);

		goto out;
	}

	/* Do checksum for process_stored_dump() */
	cb_calc_buf_checksum(arg, buf, len);

	while (remaining > 0) {
		if (hex2char(buf[i] >> 4, &print_buf[print_buf_ptr]) < 0) {
			ret = -EINVAL;
			break;
		}
		print_buf_ptr++;

		if (hex2char(buf[i] & 0xf, &print_buf[print_buf_ptr]) < 0) {
			ret = -EINVAL;
			break;
		}
		print_buf_ptr++;

		remaining--;
		i++;

		if (print_buf_ptr == PRINT_BUF_SZ) {
			flush_print_buf(sh);
		}
	}

out:
	return ret;
}

/**
 * @brief Shell command to print stored coredump data to shell
 *
 * @param sh shell instance
 * @param argc (not used)
 * @param argv (not used)
 * @return 0
 */
static int cmd_coredump_print_stored_dump(const struct shell *sh,
					  size_t argc, char **argv)
{
	int ret;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	/* Verify first to see if stored dump is valid */
	ret = coredump_flash_backend_cmd(COREDUMP_CMD_VERIFY_STORED_DUMP,
					 NULL);

	if (ret == 0) {
		shell_print(sh, "Stored coredump verification failed "
				   "or there is no stored coredump.");
		goto out;
	} else if (ret != 1) {
		shell_print(sh, "Failed to perform verify command: %d",
			    ret);
		goto out;
	}

	/* If valid, start printing to shell */
	print_buf_ptr = 0;
	(void)memset(print_buf, 0, sizeof(print_buf));

	shell_print(sh, "%s%s", COREDUMP_PREFIX_STR, COREDUMP_BEGIN_STR);

	ret = process_stored_dump(cb_print_stored_dump, (void *)sh);
	if (print_buf_ptr != 0) {
		shell_print(sh, "%s%s", COREDUMP_PREFIX_STR, print_buf);
	}

	if (backend_ctx.error != 0) {
		shell_print(sh, "%s%s", COREDUMP_PREFIX_STR,
			    COREDUMP_ERROR_STR);
	}

	shell_print(sh, "%s%s", COREDUMP_PREFIX_STR, COREDUMP_END_STR);

	if (ret == 1) {
		shell_print(sh, "Stored coredump printed.");
	} else if (ret == 0) {
		shell_print(sh, "Stored coredump verification failed "
				   "or there is no stored coredump.");
	} else {
		shell_print(sh, "Failed to print: %d", ret);
	}

out:
	return 0;
}

/**
 * @brief Shell command to erase stored coredump.
 *
 * @param sh shell instance
 * @param argc (not used)
 * @param argv (not used)
 * @return 0
 */
static int cmd_coredump_erase_stored_dump(const struct shell *sh,
					  size_t argc, char **argv)
{
	int ret;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	ret = coredump_flash_backend_cmd(COREDUMP_CMD_ERASE_STORED_DUMP,
					 NULL);

	if (ret == 0) {
		shell_print(sh, "Stored coredump erased.");
	} else {
		shell_print(sh, "Failed to perform erase command: %d", ret);
	}

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sub_coredump_error,
	SHELL_CMD(clear, NULL, "Clear Coredump error",
		  cmd_coredump_error_clear),
	SHELL_CMD(get, NULL, "Get Coredump error", cmd_coredump_error_get),
	SHELL_SUBCMD_SET_END /* Array terminated. */
);

SHELL_STATIC_SUBCMD_SET_CREATE(sub_coredump,
	SHELL_CMD(error, &sub_coredump_error,
		  "Get/clear backend error.", NULL),
	SHELL_CMD(erase, NULL,
		  "Erase stored coredump",
		  cmd_coredump_erase_stored_dump),
	SHELL_CMD(find, NULL,
		  "Query if there is a stored coredump",
		  cmd_coredump_has_stored_dump),
	SHELL_CMD(print, NULL,
		  "Print stored coredump to shell",
		  cmd_coredump_print_stored_dump),
	SHELL_CMD(verify, NULL,
		  "Verify stored coredump",
		  cmd_coredump_verify_stored_dump),
	SHELL_SUBCMD_SET_END /* Array terminated. */
);

SHELL_CMD_REGISTER(coredump, &sub_coredump,
		   "Coredump commands (flash partition backend)", NULL);

#endif /* CONFIG_DEBUG_COREDUMP_SHELL */

#endif /* FIXED_PARTITION_EXISTS(coredump_partition) */
