/*
 * Copyright (c) 2020 Google LLC.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/devicetree.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/mgmt/ec_host_cmd/ec_host_cmd.h>
#include <zephyr/mgmt/ec_host_cmd/backend.h>
#include <zephyr/sys/iterable_sections.h>
#include <stdio.h>
#include <string.h>

LOG_MODULE_REGISTER(host_cmd_handler, CONFIG_EC_HC_LOG_LEVEL);

#ifdef CONFIG_EC_HOST_CMD_INITIALIZE_AT_BOOT
#define EC_HOST_CMD_CHOSEN_BACKEND_LIST                                                            \
	zephyr_host_cmd_espi_backend, zephyr_host_cmd_shi_backend, zephyr_host_cmd_uart_backend,   \
		zephyr_host_cmd_spi_backend

#define EC_HOST_CMD_ADD_CHOSEN(chosen) COND_CODE_1(DT_NODE_EXISTS(DT_CHOSEN(chosen)), (1), (0))

#define NUMBER_OF_CHOSEN_BACKENDS                                                                  \
	FOR_EACH(EC_HOST_CMD_ADD_CHOSEN, (+), EC_HOST_CMD_CHOSEN_BACKEND_LIST)                     \
	+0

BUILD_ASSERT(NUMBER_OF_CHOSEN_BACKENDS < 2, "Number of chosen backends > 1");
#endif

#define RX_HEADER_SIZE (sizeof(struct ec_host_cmd_request_header))
#define TX_HEADER_SIZE (sizeof(struct ec_host_cmd_response_header))

COND_CODE_1(CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_DEF,
	    (static uint8_t hc_rx_buffer[CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE] __aligned(4);),
	    ())
COND_CODE_1(CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_DEF,
	    (static uint8_t hc_tx_buffer[CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_SIZE] __aligned(4);),
	    ())

#ifdef CONFIG_EC_HOST_CMD_DEDICATED_THREAD
static K_KERNEL_STACK_DEFINE(hc_stack, CONFIG_EC_HOST_CMD_HANDLER_STACK_SIZE);
#endif /* CONFIG_EC_HOST_CMD_DEDICATED_THREAD */

static struct ec_host_cmd ec_host_cmd = {
	.rx_ctx = {
			.buf = COND_CODE_1(CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_DEF, (hc_rx_buffer),
					   (NULL)),
			.len_max = COND_CODE_1(CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_DEF,
					       (CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE), (0)),
		},
	.tx = {
			.buf = COND_CODE_1(CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_DEF, (hc_tx_buffer),
					   (NULL)),
			.len_max = COND_CODE_1(CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_DEF,
					       (CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_SIZE), (0)),
		},
};

#ifdef CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS
/* Indicates that a command has sent EC_HOST_CMD_IN_PROGRESS but hasn't sent a final status */
static bool cmd_in_progress;

/* The final result of the last command that has sent EC_HOST_CMD_IN_PROGRESS */
static enum ec_host_cmd_status saved_status = EC_HOST_CMD_UNAVAILABLE;
static struct k_work work_in_progress;
ec_host_cmd_in_progress_cb_t cb_in_progress;
static void *user_data_in_progress;
#endif /* CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS */

#ifdef CONFIG_EC_HOST_CMD_LOG_SUPPRESSED
static uint16_t suppressed_cmds[CONFIG_EC_HOST_CMD_LOG_SUPPRESSED_NUMBER];
static uint16_t suppressed_cmds_count[CONFIG_EC_HOST_CMD_LOG_SUPPRESSED_NUMBER];
static int64_t suppressed_cmds_deadline = CONFIG_EC_HOST_CMD_LOG_SUPPRESSED_INTERVAL_SECS * 1000U;
static size_t suppressed_cmds_number;
#endif /* CONFIG_EC_HOST_CMD_LOG_SUPPRESSED */

static uint8_t cal_checksum(const uint8_t *const buffer, const uint16_t size)
{
	uint8_t checksum = 0;

	for (size_t i = 0; i < size; ++i) {
		checksum += buffer[i];
	}
	return (uint8_t)(-checksum);
}

#ifdef CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS
bool ec_host_cmd_send_in_progress_ended(void)
{
	return !cmd_in_progress;
}

enum ec_host_cmd_status ec_host_cmd_send_in_progress_status(void)
{
	enum ec_host_cmd_status ret = saved_status;

	saved_status = EC_HOST_CMD_UNAVAILABLE;

	return ret;
}

enum ec_host_cmd_status ec_host_cmd_send_in_progress_continue(ec_host_cmd_in_progress_cb_t cb,
							      void *user_data)
{
	if (cmd_in_progress) {
		return EC_HOST_CMD_BUSY;
	}

	cmd_in_progress = true;
	cb_in_progress = cb;
	user_data_in_progress = user_data;
	saved_status = EC_HOST_CMD_UNAVAILABLE;
	LOG_INF("HC pending");
	k_work_submit(&work_in_progress);

	return EC_HOST_CMD_SUCCESS;
}

static void handler_in_progress(struct k_work *work)
{
	if (cb_in_progress != NULL) {
		saved_status = cb_in_progress(user_data_in_progress);
		LOG_INF("HC pending done, result=%d", saved_status);
	} else {
		saved_status = EC_HOST_CMD_UNAVAILABLE;
		LOG_ERR("HC incorrect IN_PROGRESS callback");
	}
	cb_in_progress = NULL;
	cmd_in_progress = false;
}
#endif /* CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS */

#ifdef CONFIG_EC_HOST_CMD_LOG_SUPPRESSED
int ec_host_cmd_add_suppressed(uint16_t cmd_id)
{
	if (suppressed_cmds_number >= CONFIG_EC_HOST_CMD_LOG_SUPPRESSED_NUMBER) {
		return -EIO;
	}

	suppressed_cmds[suppressed_cmds_number] = cmd_id;
	++suppressed_cmds_number;

	return 0;
}

static bool ec_host_cmd_is_suppressed(uint16_t cmd_id)
{
	int i;

	for (i = 0; i < suppressed_cmds_number; i++) {
		if (suppressed_cmds[i] == cmd_id) {
			suppressed_cmds_count[i]++;

			return true;
		}
	}

	return false;
}

void ec_host_cmd_dump_suppressed(void)
{
	int i;
	int64_t uptime = k_uptime_get();

	LOG_PRINTK("[%llds HC Suppressed:", uptime / 1000U);
	for (i = 0; i < suppressed_cmds_number; i++) {
		LOG_PRINTK(" 0x%x=%d", suppressed_cmds[i], suppressed_cmds_count[i]);
		suppressed_cmds_count[i] = 0;
	}
	LOG_PRINTK("]\n");

	/* Reset the timer */
	suppressed_cmds_deadline = uptime + CONFIG_EC_HOST_CMD_LOG_SUPPRESSED_INTERVAL_SECS * 1000U;
}

static void ec_host_cmd_check_suppressed(void)
{
	if (k_uptime_get() >= suppressed_cmds_deadline) {
		ec_host_cmd_dump_suppressed();
	}
}
#endif /* CONFIG_EC_HOST_CMD_LOG_SUPPRESSED */

static void send_status_response(const struct ec_host_cmd_backend *backend,
				 struct ec_host_cmd_tx_buf *tx,
				 const enum ec_host_cmd_status status)
{
	struct ec_host_cmd_response_header *const tx_header = (void *)tx->buf;

	tx_header->prtcl_ver = 3;
	tx_header->result = status;
	tx_header->data_len = 0;
	tx_header->reserved = 0;
	tx_header->checksum = 0;
	tx_header->checksum = cal_checksum((uint8_t *)tx_header, TX_HEADER_SIZE);

	tx->len = TX_HEADER_SIZE;

	backend->api->send(backend);
}

static enum ec_host_cmd_status verify_rx(struct ec_host_cmd_rx_ctx *rx)
{
	/* rx buf and len now have valid incoming data */
	if (rx->len < RX_HEADER_SIZE) {
		return EC_HOST_CMD_REQUEST_TRUNCATED;
	}

	const struct ec_host_cmd_request_header *rx_header =
		(struct ec_host_cmd_request_header *)rx->buf;

	/* Only support version 3 */
	if (rx_header->prtcl_ver != 3) {
		return EC_HOST_CMD_INVALID_HEADER;
	}

	const uint16_t rx_valid_data_size = rx_header->data_len + RX_HEADER_SIZE;
	/*
	 * Ensure we received at least as much data as is expected.
	 * It is okay to receive more since some hardware interfaces
	 * add on extra padding bytes at the end.
	 */
	if (rx->len < rx_valid_data_size) {
		return EC_HOST_CMD_REQUEST_TRUNCATED;
	}

	/* Validate checksum */
	if (cal_checksum((uint8_t *)rx_header, rx_valid_data_size) != 0) {
		return EC_HOST_CMD_INVALID_CHECKSUM;
	}

	return EC_HOST_CMD_SUCCESS;
}

static enum ec_host_cmd_status validate_handler(const struct ec_host_cmd_handler *handler,
						const struct ec_host_cmd_handler_args *args)
{
	if (handler->min_rqt_size > args->input_buf_size) {
		return EC_HOST_CMD_REQUEST_TRUNCATED;
	}

	if (handler->min_rsp_size > args->output_buf_max) {
		return EC_HOST_CMD_INVALID_RESPONSE;
	}

	if (args->version >= NUM_BITS(handler->version_mask) ||
	    !(handler->version_mask & BIT(args->version))) {
		return EC_HOST_CMD_INVALID_VERSION;
	}

	return EC_HOST_CMD_SUCCESS;
}

static enum ec_host_cmd_status prepare_response(struct ec_host_cmd_tx_buf *tx, uint16_t len)
{
	struct ec_host_cmd_response_header *const tx_header = (void *)tx->buf;

	tx_header->prtcl_ver = 3;
	tx_header->result = EC_HOST_CMD_SUCCESS;
	tx_header->data_len = len;
	tx_header->reserved = 0;

	const uint16_t tx_valid_data_size = tx_header->data_len + TX_HEADER_SIZE;

	if (tx_valid_data_size > tx->len_max) {
		return EC_HOST_CMD_INVALID_RESPONSE;
	}

	/* Calculate checksum */
	tx_header->checksum = 0;
	tx_header->checksum = cal_checksum(tx->buf, tx_valid_data_size);

	tx->len = tx_valid_data_size;

	return EC_HOST_CMD_SUCCESS;
}

void ec_host_cmd_set_user_cb(ec_host_cmd_user_cb_t cb, void *user_data)
{
	struct ec_host_cmd *hc = &ec_host_cmd;

	hc->user_cb = cb;
	hc->user_data = user_data;
}

int ec_host_cmd_send_response(enum ec_host_cmd_status status,
			      const struct ec_host_cmd_handler_args *args)
{
	struct ec_host_cmd *hc = &ec_host_cmd;
	struct ec_host_cmd_tx_buf *tx = &hc->tx;

	if (status != EC_HOST_CMD_SUCCESS) {
		const struct ec_host_cmd_request_header *const rx_header =
			(const struct ec_host_cmd_request_header *const)hc->rx_ctx.buf;

		LOG_INF("HC 0x%04x err %d", rx_header->cmd_id, status);
		send_status_response(hc->backend, tx, status);
		return status;
	}

#ifdef CONFIG_EC_HOST_CMD_LOG_DBG_BUFFERS
	if (args->output_buf_size) {
		LOG_HEXDUMP_DBG(args->output_buf, args->output_buf_size, "HC resp:");
	}
#endif

	status = prepare_response(tx, args->output_buf_size);
	if (status != EC_HOST_CMD_SUCCESS) {
		send_status_response(hc->backend, tx, status);
		return status;
	}

	return hc->backend->api->send(hc->backend);
}

void ec_host_cmd_rx_notify(void)
{
	struct ec_host_cmd *hc = &ec_host_cmd;
	struct ec_host_cmd_rx_ctx *rx = &hc->rx_ctx;

	hc->rx_status = verify_rx(rx);

	if (!hc->rx_status && hc->user_cb) {
		hc->user_cb(rx, hc->user_data);
	}

	k_sem_give(&hc->rx_ready);
}

static void ec_host_cmd_log_request(const uint8_t *rx_buf)
{
	static uint16_t prev_cmd;
	const struct ec_host_cmd_request_header *const rx_header =
		(const struct ec_host_cmd_request_header *const)rx_buf;

#ifdef CONFIG_EC_HOST_CMD_LOG_SUPPRESSED
	if (ec_host_cmd_is_suppressed(rx_header->cmd_id)) {
		ec_host_cmd_check_suppressed();

		return;
	}
#endif /* CONFIG_EC_HOST_CMD_LOG_SUPPRESSED */

	if (IS_ENABLED(CONFIG_EC_HOST_CMD_LOG_DBG_BUFFERS)) {
		if (rx_header->data_len) {
			const uint8_t *rx_data = rx_buf + RX_HEADER_SIZE;
			static const char dbg_fmt[] = "HC 0x%04x.%d:";
			/* Use sizeof because "%04x" needs 4 bytes for command id, and
			 * %d needs 2 bytes for version, so no additional buffer is required.
			 */
			char dbg_raw[sizeof(dbg_fmt)];

			snprintf(dbg_raw, sizeof(dbg_raw), dbg_fmt, rx_header->cmd_id,
				 rx_header->cmd_ver);
			LOG_HEXDUMP_DBG(rx_data, rx_header->data_len, dbg_raw);

			return;
		}
	}

	/* In normal output mode, skip printing repeats of the same command
	 * that occur in rapid succession - such as flash commands during
	 * software sync.
	 */
	if (rx_header->cmd_id != prev_cmd) {
		prev_cmd = rx_header->cmd_id;
		LOG_INF("HC 0x%04x", rx_header->cmd_id);
	} else {
		LOG_DBG("HC 0x%04x", rx_header->cmd_id);
	}
}

FUNC_NORETURN static void ec_host_cmd_thread(void *hc_handle, void *arg2, void *arg3)
{
	ARG_UNUSED(arg2);
	ARG_UNUSED(arg3);
	enum ec_host_cmd_status status;
	struct ec_host_cmd *hc = (struct ec_host_cmd *)hc_handle;
	struct ec_host_cmd_rx_ctx *rx = &hc->rx_ctx;
	struct ec_host_cmd_tx_buf *tx = &hc->tx;
	const struct ec_host_cmd_handler *found_handler;
	const struct ec_host_cmd_request_header *const rx_header = (void *)rx->buf;
	/* The pointer to rx buffer is constant during communication */
	struct ec_host_cmd_handler_args args = {
		.output_buf = (uint8_t *)tx->buf + TX_HEADER_SIZE,
		.input_buf = rx->buf + RX_HEADER_SIZE,
		.reserved = NULL,
	};

	while (1) {
		/* Wait until RX messages is received on host interface */
		k_sem_take(&hc->rx_ready, K_FOREVER);

		ec_host_cmd_log_request(rx->buf);

		/* Check status of the rx data, that has been verified in
		 * ec_host_cmd_send_received.
		 */
		if (hc->rx_status != EC_HOST_CMD_SUCCESS) {
			ec_host_cmd_send_response(hc->rx_status, &args);
			continue;
		}

		found_handler = NULL;
		STRUCT_SECTION_FOREACH(ec_host_cmd_handler, handler) {
			if (handler->id == rx_header->cmd_id) {
				found_handler = handler;
				break;
			}
		}

		/* No handler in this image for requested command */
		if (found_handler == NULL) {
			ec_host_cmd_send_response(EC_HOST_CMD_INVALID_COMMAND, &args);
			continue;
		}

		args.command = rx_header->cmd_id;
		args.version = rx_header->cmd_ver;
		args.input_buf_size = rx_header->data_len;
		args.output_buf_max = tx->len_max - TX_HEADER_SIZE,
		args.output_buf_size = 0;

		status = validate_handler(found_handler, &args);
		if (status != EC_HOST_CMD_SUCCESS) {
			ec_host_cmd_send_response(status, &args);
			continue;
		}

		/*
		 * Pre-emptively clear the entire response buffer so we do not
		 * have any left over contents from previous host commands.
		 */
		memset(args.output_buf, 0, args.output_buf_max);

		status = found_handler->handler(&args);

		ec_host_cmd_send_response(status, &args);
	}
}

#ifndef CONFIG_EC_HOST_CMD_DEDICATED_THREAD
FUNC_NORETURN void ec_host_cmd_task(void)
{
	ec_host_cmd_thread(&ec_host_cmd, NULL, NULL);
}
#endif

int ec_host_cmd_init(struct ec_host_cmd_backend *backend)
{
	struct ec_host_cmd *hc = &ec_host_cmd;
	int ret;
	uint8_t *handler_tx_buf, *handler_rx_buf;
	uint8_t *handler_tx_buf_end, *handler_rx_buf_end;
	uint8_t *backend_tx_buf, *backend_rx_buf;

	hc->backend = backend;

	/* Allow writing to rx buff at startup */
	k_sem_init(&hc->rx_ready, 0, 1);

#ifdef CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS
	k_work_init(&work_in_progress, handler_in_progress);
#endif /* CONFIG_EC_HOST_CMD_IN_PROGRESS_STATUS */

	handler_tx_buf = hc->tx.buf;
	handler_rx_buf = hc->rx_ctx.buf;
	handler_tx_buf_end = handler_tx_buf + CONFIG_EC_HOST_CMD_HANDLER_TX_BUFFER_SIZE;
	handler_rx_buf_end = handler_rx_buf + CONFIG_EC_HOST_CMD_HANDLER_RX_BUFFER_SIZE;

	ret = backend->api->init(backend, &hc->rx_ctx, &hc->tx);

	backend_tx_buf = hc->tx.buf;
	backend_rx_buf = hc->rx_ctx.buf;

	if (ret != 0) {
		return ret;
	}

	if (!backend_tx_buf || !backend_rx_buf) {
		LOG_ERR("No buffer for Host Command communication");
		return -EIO;
	}

	/* Check if a backend uses provided buffers. The buffer pointers can be shifted within the
	 * buffer to make space for preamble. Make sure the rx/tx pointers are within the provided
	 * buffers ranges.
	 */
	if ((handler_tx_buf &&
	     !((handler_tx_buf <= backend_tx_buf) && (handler_tx_buf_end > backend_tx_buf))) ||
	    (handler_rx_buf &&
	     !((handler_rx_buf <= backend_rx_buf) && (handler_rx_buf_end > backend_rx_buf)))) {
		LOG_WRN("Host Command handler provided unused buffer");
	}

#ifdef CONFIG_EC_HOST_CMD_DEDICATED_THREAD
	k_thread_create(&hc->thread, hc_stack, CONFIG_EC_HOST_CMD_HANDLER_STACK_SIZE,
			ec_host_cmd_thread, (void *)hc, NULL, NULL, CONFIG_EC_HOST_CMD_HANDLER_PRIO,
			0, K_NO_WAIT);
	k_thread_name_set(&hc->thread, "ec_host_cmd");
#endif /* CONFIG_EC_HOST_CMD_DEDICATED_THREAD */

	return 0;
}

const struct ec_host_cmd *ec_host_cmd_get_hc(void)
{
	return &ec_host_cmd;
}
