/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/sys/ring_buffer.h>
#include <zephyr/sys/atomic.h>
#include <zephyr/mgmt/mcumgr/transport/smp_shell.h>
#include <zephyr/shell/shell_uart.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/serial/uart_async_rx.h>
#include <zephyr/init.h>
#include <zephyr/logging/log.h>
#include <zephyr/net/buf.h>

#define LOG_MODULE_NAME shell_uart
LOG_MODULE_REGISTER(shell_uart);

#ifdef CONFIG_SHELL_BACKEND_SERIAL_RX_POLL_PERIOD
#define RX_POLL_PERIOD K_MSEC(CONFIG_SHELL_BACKEND_SERIAL_RX_POLL_PERIOD)
#else
#define RX_POLL_PERIOD K_NO_WAIT
#endif

#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL
NET_BUF_POOL_DEFINE(smp_shell_rx_pool, CONFIG_MCUMGR_TRANSPORT_SHELL_RX_BUF_COUNT,
		    SMP_SHELL_RX_BUF_SIZE, 0, NULL);
#endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */

static void async_callback(const struct device *dev, struct uart_event *evt, void *user_data)
{
	struct shell_uart_async *sh_uart = (struct shell_uart_async *)user_data;

	switch (evt->type) {
	case  UART_TX_DONE:
		k_sem_give(&sh_uart->tx_sem);
		break;
	case  UART_RX_RDY:
		uart_async_rx_on_rdy(&sh_uart->async_rx, evt->data.rx.buf, evt->data.rx.len);
		sh_uart->common.handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_uart->common.context);
		break;
	case  UART_RX_BUF_REQUEST:
	{
		uint8_t *buf = uart_async_rx_buf_req(&sh_uart->async_rx);
		size_t len = uart_async_rx_get_buf_len(&sh_uart->async_rx);

		if (buf) {
			int err = uart_rx_buf_rsp(dev, buf, len);

			if (err < 0) {
				uart_async_rx_on_buf_rel(&sh_uart->async_rx, buf);
			}
		} else {
			atomic_inc(&sh_uart->pending_rx_req);
		}

		break;
	}
	case  UART_RX_BUF_RELEASED:
		uart_async_rx_on_buf_rel(&sh_uart->async_rx, evt->data.rx_buf.buf);
		break;
	case  UART_RX_DISABLED:
		break;
	default:
		break;
	};
}

static void uart_rx_handle(const struct device *dev, struct shell_uart_int_driven *sh_uart)
{
	uint8_t *data;
	uint32_t len;
	uint32_t rd_len;
	bool new_data = false;
#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL
	struct smp_shell_data *const smp = &sh_uart->common.smp;
#endif

	do {
		len = ring_buf_put_claim(&sh_uart->rx_ringbuf, &data,
					 sh_uart->rx_ringbuf.size);

		if (len > 0) {
			rd_len = uart_fifo_read(dev, data, len);

			/* If there is any new data to be either taken into
			 * ring buffer or consumed by the SMP, signal the
			 * shell_thread.
			 */
			if (rd_len > 0) {
				new_data = true;
			}
#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL
			/* Divert bytes from shell handling if it is
			 * part of an mcumgr frame.
			 */
			size_t i = smp_shell_rx_bytes(smp, data, rd_len);

			rd_len -= i;

			if (rd_len) {
				for (uint32_t j = 0; j < rd_len; j++) {
					data[j] = data[i + j];
				}
			}
#endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */
			int err = ring_buf_put_finish(&sh_uart->rx_ringbuf, rd_len);
			(void)err;
			__ASSERT_NO_MSG(err == 0);
		} else {
			uint8_t dummy;

			/* No space in the ring buffer - consume byte. */
			LOG_WRN("RX ring buffer full.");

			rd_len = uart_fifo_read(dev, &dummy, 1);
#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL
			/* If successful in getting byte from the fifo, try
			 * feeding it to SMP as a part of mcumgr frame.
			 */
			if ((rd_len != 0) && (smp_shell_rx_bytes(smp, &dummy, 1) == 1)) {
				new_data = true;
			}
#endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */
		}
	} while (rd_len && (rd_len == len));

	if (new_data) {
		sh_uart->common.handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_uart->common.context);
	}
}

static bool uart_dtr_check(const struct device *dev)
{
	BUILD_ASSERT(!IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_CHECK_DTR) ||
		IS_ENABLED(CONFIG_UART_LINE_CTRL),
		"DTR check requires CONFIG_UART_LINE_CTRL");

	if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_CHECK_DTR)) {
		int dtr, err;

		err = uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr);
		if (err == -ENOSYS || err == -ENOTSUP) {
			return true;
		}

		return dtr;
	}

	return true;
}

static void dtr_timer_handler(struct k_timer *timer)
{
	struct shell_uart_int_driven *sh_uart = k_timer_user_data_get(timer);

	if (!uart_dtr_check(sh_uart->common.dev)) {
		return;
	}

	/* DTR is active, stop timer and start TX */
	k_timer_stop(timer);
	uart_irq_tx_enable(sh_uart->common.dev);
}

static void uart_tx_handle(const struct device *dev, struct shell_uart_int_driven *sh_uart)
{
	uint32_t len;
	const uint8_t *data;

	if (!uart_dtr_check(dev)) {
		/* Wait for DTR signal before sending anything to output. */
		uart_irq_tx_disable(dev);
		k_timer_start(&sh_uart->dtr_timer, K_MSEC(100), K_MSEC(100));
		return;
	}

	len = ring_buf_get_claim(&sh_uart->tx_ringbuf, (uint8_t **)&data,
				 sh_uart->tx_ringbuf.size);
	if (len) {
		int err;

		len = uart_fifo_fill(dev, data, len);
		err = ring_buf_get_finish(&sh_uart->tx_ringbuf, len);
		__ASSERT_NO_MSG(err == 0);
		ARG_UNUSED(err);
	} else {
		uart_irq_tx_disable(dev);
		sh_uart->tx_busy = 0;
	}

	sh_uart->common.handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_uart->common.context);
}

static void uart_callback(const struct device *dev, void *user_data)
{
	struct shell_uart_int_driven *sh_uart = (struct shell_uart_int_driven *)user_data;

	uart_irq_update(dev);

	if (uart_irq_rx_ready(dev)) {
		uart_rx_handle(dev, sh_uart);
	}

	if (uart_irq_tx_ready(dev)) {
		uart_tx_handle(dev, sh_uart);
	}
}

static void irq_init(struct shell_uart_int_driven *sh_uart)
{
	const struct device *dev = sh_uart->common.dev;

	ring_buf_init(&sh_uart->rx_ringbuf, CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE,
		      sh_uart->rx_buf);
	ring_buf_init(&sh_uart->tx_ringbuf, CONFIG_SHELL_BACKEND_SERIAL_TX_RING_BUFFER_SIZE,
		      sh_uart->tx_buf);
	sh_uart->tx_busy = 0;
	uart_irq_callback_user_data_set(dev, uart_callback, (void *)sh_uart);
	uart_irq_rx_enable(dev);

	if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_CHECK_DTR)) {
		k_timer_init(&sh_uart->dtr_timer, dtr_timer_handler, NULL);
		k_timer_user_data_set(&sh_uart->dtr_timer, (void *)sh_uart);
	}
}

static int rx_enable(const struct device *dev, uint8_t *buf, size_t len)
{
	return uart_rx_enable(dev, buf, len, 10000);
}

static void async_init(struct shell_uart_async *sh_uart)
{
	const struct device *dev = sh_uart->common.dev;
	struct uart_async_rx *async_rx = &sh_uart->async_rx;
	int err;

	sh_uart->async_rx_config = (struct uart_async_rx_config){
		.buffer = sh_uart->rx_data,
		.length = ASYNC_RX_BUF_SIZE,
		.buf_cnt = CONFIG_SHELL_BACKEND_SERIAL_ASYNC_RX_BUFFER_COUNT,
	};

	k_sem_init(&sh_uart->tx_sem, 0, 1);

	err = uart_async_rx_init(async_rx, &sh_uart->async_rx_config);
	(void)err;
	__ASSERT_NO_MSG(err == 0);

	uint8_t *buf = uart_async_rx_buf_req(async_rx);

	err = uart_callback_set(dev, async_callback, (void *)sh_uart);
	(void)err;
	__ASSERT_NO_MSG(err == 0);

	err = rx_enable(dev, buf, uart_async_rx_get_buf_len(async_rx));
	(void)err;
	__ASSERT_NO_MSG(err == 0);
}

static void polling_rx_timeout_handler(struct k_timer *timer)
{
	uint8_t c;
	struct shell_uart_polling *sh_uart = k_timer_user_data_get(timer);

	while (uart_poll_in(sh_uart->common.dev, &c) == 0) {
		if (ring_buf_put(&sh_uart->rx_ringbuf, &c, 1) == 0U) {
			/* ring buffer full. */
			LOG_WRN("RX ring buffer full.");
		}
		sh_uart->common.handler(SHELL_TRANSPORT_EVT_RX_RDY, sh_uart->common.context);
	}
}

static void polling_init(struct shell_uart_polling *sh_uart)
{
	k_timer_init(&sh_uart->rx_timer, polling_rx_timeout_handler, NULL);
	k_timer_user_data_set(&sh_uart->rx_timer, (void *)sh_uart);
	k_timer_start(&sh_uart->rx_timer, RX_POLL_PERIOD, RX_POLL_PERIOD);

	ring_buf_init(&sh_uart->rx_ringbuf, CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE,
		      sh_uart->rx_buf);
}

static int init(const struct shell_transport *transport,
		const void *config,
		shell_transport_handler_t evt_handler,
		void *context)
{
	struct shell_uart_common *common = (struct shell_uart_common *)transport->ctx;

	common->dev = (const struct device *)config;
	common->handler = evt_handler;
	common->context = context;

#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL
	common->smp.buf_pool = &smp_shell_rx_pool;
	k_fifo_init(&common->smp.buf_ready);
#endif

	if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_ASYNC)) {
		async_init((struct shell_uart_async *)transport->ctx);
	} else if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN)) {
		irq_init((struct shell_uart_int_driven *)transport->ctx);
	} else {
		polling_init((struct shell_uart_polling *)transport->ctx);
	}

	return 0;
}

static void irq_uninit(struct shell_uart_int_driven *sh_uart)
{
	const struct device *dev = sh_uart->common.dev;

	k_timer_stop(&sh_uart->dtr_timer);
	uart_irq_tx_disable(dev);
	uart_irq_rx_disable(dev);
}

static void async_uninit(struct shell_uart_async *sh_uart)
{
}

static void polling_uninit(struct shell_uart_polling *sh_uart)
{
	k_timer_stop(&sh_uart->rx_timer);
}

static int uninit(const struct shell_transport *transport)
{
	if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_ASYNC)) {
		async_uninit((struct shell_uart_async *)transport->ctx);
	} else if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN)) {
		irq_uninit((struct shell_uart_int_driven *)transport->ctx);
	} else {
		polling_uninit((struct shell_uart_polling *)transport->ctx);
	}

	return 0;
}

static int enable(const struct shell_transport *transport, bool blocking_tx)
{
	struct shell_uart_common *sh_uart = (struct shell_uart_common *)transport->ctx;

	sh_uart->blocking_tx = blocking_tx;

	if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN) && blocking_tx) {
		uart_irq_tx_disable(sh_uart->dev);
	}

	return 0;
}

static int polling_write(struct shell_uart_common *sh_uart,
			 const void *data, size_t length, size_t *cnt)
{
	const uint8_t *data8 = (const uint8_t *)data;

	for (size_t i = 0; i < length; i++) {
		uart_poll_out(sh_uart->dev, data8[i]);
	}

	*cnt = length;

	sh_uart->handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_uart->context);

	return 0;
}

static int irq_write(struct shell_uart_int_driven *sh_uart,
		 const void *data, size_t length, size_t *cnt)
{
	*cnt = ring_buf_put(&sh_uart->tx_ringbuf, data, length);

	if (atomic_set(&sh_uart->tx_busy, 1) == 0) {
		uart_irq_tx_enable(sh_uart->common.dev);
	}

	return 0;
}

static int async_write(struct shell_uart_async *sh_uart,
		       const void *data, size_t length, size_t *cnt)
{
	int err;

	err = uart_tx(sh_uart->common.dev, data, length, SYS_FOREVER_US);
	if (err < 0) {
		*cnt = 0;
		return err;
	}

	err = k_sem_take(&sh_uart->tx_sem, K_FOREVER);
	*cnt = length;

	sh_uart->common.handler(SHELL_TRANSPORT_EVT_TX_RDY, sh_uart->common.context);

	return err;
}

static int write(const struct shell_transport *transport,
		 const void *data, size_t length, size_t *cnt)
{
	struct shell_uart_common *sh_uart = (struct shell_uart_common *)transport->ctx;

	if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_POLLING) || sh_uart->blocking_tx) {
		return polling_write(sh_uart, data, length, cnt);
	} else if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN)) {
		return irq_write((struct shell_uart_int_driven *)transport->ctx, data, length, cnt);
	} else {
		return async_write((struct shell_uart_async *)transport->ctx, data, length, cnt);
	}
}

static int irq_read(struct shell_uart_int_driven *sh_uart,
		    void *data, size_t length, size_t *cnt)
{
	*cnt = ring_buf_get(&sh_uart->rx_ringbuf, data, length);

	return 0;
}

static int polling_read(struct shell_uart_polling *sh_uart,
			void *data, size_t length, size_t *cnt)
{
	*cnt = ring_buf_get(&sh_uart->rx_ringbuf, data, length);

	return 0;
}

static int async_read(struct shell_uart_async *sh_uart,
		      void *data, size_t length, size_t *cnt)
{
	uint8_t *buf;
	size_t blen;
	struct uart_async_rx *async_rx = &sh_uart->async_rx;

	blen = uart_async_rx_data_claim(async_rx, &buf, length);
#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL
	struct smp_shell_data *const smp = &sh_uart->common.smp;
	size_t sh_cnt = 0;

	for (size_t i = 0; i < blen; i++) {
		if (smp_shell_rx_bytes(smp, &buf[i], 1) == 0) {
			((uint8_t *)data)[sh_cnt++] = buf[i];
		}
	}
#else
	size_t sh_cnt = blen;

	memcpy(data, buf, blen);
#endif
	bool buf_available = uart_async_rx_data_consume(async_rx, sh_cnt);
	*cnt = sh_cnt;

	if (sh_uart->pending_rx_req && buf_available) {
		uint8_t *buf = uart_async_rx_buf_req(async_rx);
		size_t len = uart_async_rx_get_buf_len(async_rx);
		int err;

		__ASSERT_NO_MSG(buf != NULL);
		atomic_dec(&sh_uart->pending_rx_req);
		err = uart_rx_buf_rsp(sh_uart->common.dev, buf, len);
		/* If it is too late and RX is disabled then re-enable it. */
		if (err < 0) {
			if (err == -EACCES) {
				sh_uart->pending_rx_req = 0;
				err = rx_enable(sh_uart->common.dev, buf, len);
			} else {
				return err;
			}
		}
	}

	return 0;
}

static int read(const struct shell_transport *transport,
		void *data, size_t length, size_t *cnt)
{
	if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_INTERRUPT_DRIVEN)) {
		return irq_read((struct shell_uart_int_driven *)transport->ctx, data, length, cnt);
	} else if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_API_ASYNC)) {
		return async_read((struct shell_uart_async *)transport->ctx, data, length, cnt);
	} else {
		return polling_read((struct shell_uart_polling *)transport->ctx, data, length, cnt);
	}
}

#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL
static void update(const struct shell_transport *transport)
{
	/*
	 * This is dependent on the fact that `struct shell_uart_common`
	 * is always the first member, regardless of the UART configuration
	 */
	struct shell_uart_common *sh_uart = (struct shell_uart_common *)transport->ctx;

	smp_shell_process(&sh_uart->smp);
}
#endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */

const struct shell_transport_api shell_uart_transport_api = {
	.init = init,
	.uninit = uninit,
	.enable = enable,
	.write = write,
	.read = read,
#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL
	.update = update,
#endif /* CONFIG_MCUMGR_TRANSPORT_SHELL */
};

SHELL_UART_DEFINE(shell_transport_uart);
SHELL_DEFINE(shell_uart, CONFIG_SHELL_PROMPT_UART, &shell_transport_uart,
	     CONFIG_SHELL_BACKEND_SERIAL_LOG_MESSAGE_QUEUE_SIZE,
	     CONFIG_SHELL_BACKEND_SERIAL_LOG_MESSAGE_QUEUE_TIMEOUT,
	     SHELL_FLAG_OLF_CRLF);

#ifdef CONFIG_MCUMGR_TRANSPORT_SHELL
struct smp_shell_data *shell_uart_smp_shell_data_get_ptr(void)
{
	struct shell_uart_common *common = (struct shell_uart_common *)shell_transport_uart.ctx;

	return &common->smp;
}
#endif

static int enable_shell_uart(void)
{
	const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart));
	bool log_backend = CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL > 0;
	uint32_t level =
		(CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL > LOG_LEVEL_DBG) ?
		CONFIG_LOG_MAX_LEVEL : CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL;
	static const struct shell_backend_config_flags cfg_flags =
					SHELL_DEFAULT_BACKEND_CONFIG_FLAGS;

	if (!device_is_ready(dev)) {
		return -ENODEV;
	}

	if (IS_ENABLED(CONFIG_MCUMGR_TRANSPORT_SHELL)) {
		smp_shell_init();
	}

	shell_init(&shell_uart, dev, cfg_flags, log_backend, level);

	return 0;
}

SYS_INIT(enable_shell_uart, POST_KERNEL,
	 CONFIG_SHELL_BACKEND_SERIAL_INIT_PRIORITY);

const struct shell *shell_backend_uart_get_ptr(void)
{
	return &shell_uart;
}
