/*
 * 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 (hc->state != EC_HOST_CMD_STATE_PROCESSING) {
		LOG_ERR("Unexpected state while sending");
		return -ENOTSUP;
	}
	hc->state = EC_HOST_CMD_STATE_SENDING;

	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,
	};

	__ASSERT(hc->state != EC_HOST_CMD_STATE_DISABLED, "HC backend not initialized");

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

		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;
	}

	hc->state = EC_HOST_CMD_STATE_RECEIVING;

	/* 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;
}
