/*
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/drivers/serial/uart_async_to_irq.h>
#include <string.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(UART_ASYNC_TO_IRQ_LOG_NAME, CONFIG_UART_LOG_LEVEL);

/* Internal state flags. */

/* RX interrupt enabled. */
#define A2I_RX_IRQ_ENABLED	BIT(0)

/* TX interrupt enabled. */
#define A2I_TX_IRQ_ENABLED	BIT(1)

/* Error interrupt enabled. */
#define A2I_ERR_IRQ_ENABLED	BIT(2)

/* Receiver to be kept enabled. */
#define A2I_RX_ENABLE		BIT(3)

/* TX busy. */
#define A2I_TX_BUSY		BIT(4)

static struct uart_async_to_irq_data *get_data(const struct device *dev)
{
	struct uart_async_to_irq_data **data = dev->data;

	return *data;
}

static const struct uart_async_to_irq_config *get_config(const struct device *dev)
{
	const struct uart_async_to_irq_config * const *config = dev->config;

	return *config;
}

/* Function calculates RX timeout based on baudrate. */
static uint32_t get_rx_timeout(const struct device *dev)
{
	struct uart_config cfg;
	int err;
	uint32_t baudrate;

	err = uart_config_get(dev, &cfg);
	if (err == 0) {
		baudrate = cfg.baudrate;
	} else {
		baudrate = get_config(dev)->baudrate;
	}

	uint32_t us = (CONFIG_UART_ASYNC_TO_INT_DRIVEN_RX_TIMEOUT * 1000000) / baudrate;

	return us;
}

static int rx_enable(const struct device *dev,
		     struct uart_async_to_irq_data *data,
		     uint8_t *buf,
		     size_t len)
{
	int err;
	const struct uart_async_to_irq_config *config = get_config(dev);

	err = config->api->rx_enable(dev, buf, len, get_rx_timeout(dev));

	return err;
}

static int try_rx_enable(const struct device *dev, struct uart_async_to_irq_data *data)
{
	uint8_t *buf = uart_async_rx_buf_req(&data->rx.async_rx);
	size_t len = uart_async_rx_get_buf_len(&data->rx.async_rx);

	if (buf == NULL) {
		return -EBUSY;
	}

	return rx_enable(dev, data, buf, len);
}

static void on_rx_buf_req(const struct device *dev,
			  const struct uart_async_to_irq_config *config,
			  struct uart_async_to_irq_data *data)
{
	struct uart_async_rx *async_rx = &data->rx.async_rx;
	uint8_t *buf = uart_async_rx_buf_req(async_rx);
	size_t len = uart_async_rx_get_buf_len(async_rx);

	if (buf) {
		int err = config->api->rx_buf_rsp(dev, buf, len);

		if (err < 0) {
			uart_async_rx_on_buf_rel(async_rx, buf);
		}
	} else {
		atomic_inc(&data->rx.pending_buf_req);
	}
}

static void on_rx_dis(const struct device *dev, struct uart_async_to_irq_data *data)
{
	if (data->flags & A2I_RX_ENABLE) {
		int err;

		err = try_rx_enable(dev, data);
		if (err == 0) {
			data->rx.pending_buf_req = 0;
		}

		LOG_INST_DBG(get_config(dev)->log, "Reenabling RX from RX_DISABLED (err:%d)", err);
		__ASSERT((err >= 0) || (err == -EBUSY), "err: %d", err);
		return;
	}

	k_sem_give(&data->rx.sem);
}

static void uart_async_to_irq_callback(const struct device *dev,
					struct uart_event *evt,
					void *user_data)
{
	struct uart_async_to_irq_data *data = (struct uart_async_to_irq_data *)user_data;
	const struct uart_async_to_irq_config *config = get_config(dev);
	bool call_handler = false;

	switch (evt->type) {
	case UART_TX_DONE:
		atomic_and(&data->flags, ~A2I_TX_BUSY);
		call_handler = data->flags & A2I_TX_IRQ_ENABLED;
		break;
	case UART_RX_RDY:
		uart_async_rx_on_rdy(&data->rx.async_rx, evt->data.rx.buf, evt->data.rx.len);
		call_handler = data->flags & A2I_RX_IRQ_ENABLED;
		break;
	case UART_RX_BUF_REQUEST:
		on_rx_buf_req(dev, config, data);
		break;
	case UART_RX_BUF_RELEASED:
		uart_async_rx_on_buf_rel(&data->rx.async_rx, evt->data.rx_buf.buf);
		break;
	case UART_RX_STOPPED:
		call_handler = data->flags & A2I_ERR_IRQ_ENABLED;
		break;
	case UART_RX_DISABLED:
		on_rx_dis(dev, data);
		break;
	default:
		break;
	}

	if (data->callback && call_handler) {
		atomic_inc(&data->irq_req);
		config->trampoline(dev);
	}
}

int z_uart_async_to_irq_fifo_fill(const struct device *dev, const uint8_t *buf, int len)
{
	struct uart_async_to_irq_data *data = get_data(dev);
	const struct uart_async_to_irq_config *config = get_config(dev);
	int err;

	len = MIN(len, data->tx.len);
	if (atomic_or(&data->flags, A2I_TX_BUSY) & A2I_TX_BUSY) {
		return 0;
	}

	memcpy(data->tx.buf, buf, len);

	err = config->api->tx(dev, data->tx.buf, len, SYS_FOREVER_US);
	if (err < 0) {
		atomic_and(&data->flags, ~A2I_TX_BUSY);
		return 0;
	}

	return len;
}

/** Interrupt driven FIFO read function */
int z_uart_async_to_irq_fifo_read(const struct device *dev,
				uint8_t *buf,
				const int len)
{
	struct uart_async_to_irq_data *data = get_data(dev);
	const struct uart_async_to_irq_config *config = get_config(dev);
	struct uart_async_rx *async_rx = &data->rx.async_rx;
	size_t claim_len;
	uint8_t *claim_buf;

	claim_len = uart_async_rx_data_claim(async_rx, &claim_buf, len);
	if (claim_len == 0) {
		return 0;
	}

	memcpy(buf, claim_buf, claim_len);
	bool buf_available = uart_async_rx_data_consume(async_rx, claim_len);

	if (data->rx.pending_buf_req && buf_available) {
		buf = uart_async_rx_buf_req(async_rx);
		__ASSERT_NO_MSG(buf != NULL);
		int err;
		size_t rx_len = uart_async_rx_get_buf_len(async_rx);

		atomic_dec(&data->rx.pending_buf_req);
		err = config->api->rx_buf_rsp(dev, buf, rx_len);
		if (err < 0) {
			if (err == -EACCES) {
				data->rx.pending_buf_req = 0;
				err = rx_enable(dev, data, buf, rx_len);
			}
			if (err < 0) {
				return err;
			}
		}
	}

	return (int)claim_len;
}

static void dir_disable(const struct device *dev, uint32_t flag)
{
	struct uart_async_to_irq_data *data = get_data(dev);

	atomic_and(&data->flags, ~flag);
}

static void dir_enable(const struct device *dev, uint32_t flag)
{
	struct uart_async_to_irq_data *data = get_data(dev);

	atomic_or(&data->flags, flag);

	atomic_inc(&data->irq_req);
	get_config(dev)->trampoline(dev);
}

/** Interrupt driven transfer enabling function */
void z_uart_async_to_irq_irq_tx_enable(const struct device *dev)
{
	dir_enable(dev, A2I_TX_IRQ_ENABLED);
}

/** Interrupt driven transfer disabling function */
void z_uart_async_to_irq_irq_tx_disable(const struct device *dev)
{
	dir_disable(dev, A2I_TX_IRQ_ENABLED);
}

/** Interrupt driven transfer ready function */
int z_uart_async_to_irq_irq_tx_ready(const struct device *dev)
{
	struct uart_async_to_irq_data *data = get_data(dev);

	return (data->flags & A2I_TX_IRQ_ENABLED) && !(data->flags & A2I_TX_BUSY);
}

/** Interrupt driven receiver enabling function */
void z_uart_async_to_irq_irq_rx_enable(const struct device *dev)
{
	dir_enable(dev, A2I_RX_IRQ_ENABLED);
}

/** Interrupt driven receiver disabling function */
void z_uart_async_to_irq_irq_rx_disable(const struct device *dev)
{
	dir_disable(dev, A2I_RX_IRQ_ENABLED);
}

/** Interrupt driven transfer complete function */
int z_uart_async_to_irq_irq_tx_complete(const struct device *dev)
{
	return z_uart_async_to_irq_irq_tx_ready(dev);
}

/** Interrupt driven receiver ready function */
int z_uart_async_to_irq_irq_rx_ready(const struct device *dev)
{
	struct uart_async_to_irq_data *data = get_data(dev);

	return (data->flags & A2I_RX_IRQ_ENABLED) && (data->rx.async_rx.pending_bytes > 0);
}

/** Interrupt driven error enabling function */
void z_uart_async_to_irq_irq_err_enable(const struct device *dev)
{
	dir_enable(dev, A2I_ERR_IRQ_ENABLED);
}

/** Interrupt driven error disabling function */
void z_uart_async_to_irq_irq_err_disable(const struct device *dev)
{
	dir_disable(dev, A2I_ERR_IRQ_ENABLED);
}

/** Interrupt driven pending status function */
int z_uart_async_to_irq_irq_is_pending(const struct device *dev)
{
	return z_uart_async_to_irq_irq_tx_ready(dev) || z_uart_async_to_irq_irq_rx_ready(dev);
}

/** Interrupt driven interrupt update function */
int z_uart_async_to_irq_irq_update(const struct device *dev)
{
	return 1;
}

/** Set the irq callback function */
void z_uart_async_to_irq_irq_callback_set(const struct device *dev,
			 uart_irq_callback_user_data_t cb,
			 void *user_data)
{
	struct uart_async_to_irq_data *data = get_data(dev);

	data->callback = cb;
	data->user_data = user_data;
}

int uart_async_to_irq_rx_enable(const struct device *dev)
{
	struct uart_async_to_irq_data *data = get_data(dev);
	const struct uart_async_to_irq_config *config = get_config(dev);
	int err;

	err = config->api->callback_set(dev, uart_async_to_irq_callback, data);
	if (err < 0) {
		return err;
	}

	uart_async_rx_reset(&data->rx.async_rx);

	err = try_rx_enable(dev, data);
	if (err == 0) {
		atomic_or(&data->flags, A2I_RX_ENABLE);
	}

	return err;
}

int uart_async_to_irq_rx_disable(const struct device *dev)
{
	struct uart_async_to_irq_data *data = get_data(dev);
	const struct uart_async_to_irq_config *config = get_config(dev);
	int err;

	if (atomic_and(&data->flags, ~A2I_RX_ENABLE) & A2I_RX_ENABLE) {
		err = config->api->rx_disable(dev);
		if (err < 0) {
			return err;
		}
		k_sem_take(&data->rx.sem, K_FOREVER);
	}

	return 0;
}

void uart_async_to_irq_trampoline_cb(const struct device *dev)
{
	struct uart_async_to_irq_data *data = get_data(dev);

	do {
		data->callback(dev, data->user_data);
	} while (atomic_dec(&data->irq_req) > 1);
}

int uart_async_to_irq_init(struct uart_async_to_irq_data *data,
			   const struct uart_async_to_irq_config *config)
{
	data->tx.buf = config->tx_buf;
	data->tx.len = config->tx_len;

	k_sem_init(&data->rx.sem, 0, 1);

	return uart_async_rx_init(&data->rx.async_rx, &config->async_rx);
}
