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

#include <errno.h>
#include <sys/util.h>

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

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

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

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

/* Log Buffer */
static char log_buf[LOG_BUF_SZ_RAW];

static int error;

static void coredump_logging_backend_start(void)
{
	/* Reset error */
	error = 0;

	while (LOG_PROCESS())
		;

	LOG_PANIC();
	LOG_ERR(COREDUMP_PREFIX_STR COREDUMP_BEGIN_STR);
}

static void coredump_logging_backend_end(void)
{
	if (error != 0) {
		LOG_ERR(COREDUMP_PREFIX_STR COREDUMP_ERROR_STR);
	}

	LOG_ERR(COREDUMP_PREFIX_STR COREDUMP_END_STR);
}

static void coredump_logging_backend_buffer_output(uint8_t *buf, size_t buflen)
{
	uint8_t log_ptr = 0;
	size_t remaining = buflen;
	size_t i = 0;

	if ((buf == NULL) || (buflen == 0)) {
		error = -EINVAL;
		remaining = 0;
	}

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

		if (hex2char(buf[i] & 0xf, &log_buf[log_ptr]) < 0) {
			error = -EINVAL;
			break;
		}
		log_ptr++;

		i++;
		remaining--;

		if ((log_ptr >= LOG_BUF_SZ) || (remaining == 0)) {
			log_buf[log_ptr] = '\0';
			LOG_ERR(COREDUMP_PREFIX_STR "%s", log_strdup(log_buf));
			log_ptr = 0;
		}
	}
}

static int coredump_logging_backend_query(enum coredump_query_id query_id,
					  void *arg)
{
	int ret;

	switch (query_id) {
	case COREDUMP_QUERY_GET_ERROR:
		ret = error;
		break;
	default:
		ret = -ENOTSUP;
		break;
	}

	return ret;
}

static int coredump_logging_backend_cmd(enum coredump_cmd_id cmd_id,
					void *arg)
{
	int ret;

	switch (cmd_id) {
	case COREDUMP_CMD_CLEAR_ERROR:
		ret = 0;
		error = 0;
		break;
	default:
		ret = -ENOTSUP;
		break;
	}

	return ret;
}


struct coredump_backend_api coredump_backend_logging = {
	.start = coredump_logging_backend_start,
	.end = coredump_logging_backend_end,
	.buffer_output = coredump_logging_backend_buffer_output,
	.query = coredump_logging_backend_query,
	.cmd = coredump_logging_backend_cmd,
};


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

static int cmd_coredump_error_get(const struct shell *shell,
				  size_t argc, char **argv)
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

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

	return 0;
}

static int cmd_coredump_error_clear(const struct shell *shell,
				    size_t argc, char **argv)
{
	error = 0;

	shell_print(shell, "Error cleared.");

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sub_coredump_error,
	SHELL_CMD(get, NULL, "Get Coredump error", cmd_coredump_error_get),
	SHELL_CMD(clear, NULL, "Clear Coredump error",
		  cmd_coredump_error_clear),
	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_SUBCMD_SET_END /* Array terminated. */
);

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

#endif /* CONFIG_DEBUG_COREDUMP_SHELL */
