/** @file
 * @brief interface for modem context
 *
 * UART-based modem interface implementation for modem context driver.
 */

/*
 * Copyright (c) 2019 Foundries.io
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(modem_iface_uart, CONFIG_MODEM_LOG_LEVEL);

#include <zephyr/kernel.h>
#include <zephyr/drivers/uart.h>

#include "modem_context.h"
#include "modem_iface_uart.h"

/**
 * @brief  Drains UART.
 *
 * @note   Discards remaining data.
 *
 * @param  *iface: modem interface.
 *
 * @retval None.
 */
static void modem_iface_uart_flush(struct modem_iface *iface)
{
	uint8_t c;

	while (uart_fifo_read(iface->dev, &c, 1) > 0) {
		continue;
	}
}

/**
 * @brief  Modem interface interrupt handler.
 *
 * @note   Fills interfaces ring buffer with received data.
 *         When ring buffer is full the data is discarded.
 *
 * @param  *uart_dev: uart device.
 *
 * @retval None.
 */
static void modem_iface_uart_isr(const struct device *uart_dev,
				 void *user_data)
{
	struct modem_context *ctx;
	struct modem_iface_uart_data *data;
	int rx = 0, ret;
	uint8_t *dst;
	uint32_t partial_size = 0;
	uint32_t total_size = 0;

	ARG_UNUSED(user_data);

	/* lookup the modem context */
	ctx = modem_context_from_iface_dev(uart_dev);
	if (!ctx || !ctx->iface.iface_data) {
		return;
	}

	data = (struct modem_iface_uart_data *)(ctx->iface.iface_data);
	/* get all of the data off UART as fast as we can */
	while (uart_irq_update(ctx->iface.dev) &&
	       uart_irq_rx_ready(ctx->iface.dev)) {
		if (!partial_size) {
			partial_size = ring_buf_put_claim(&data->rx_rb, &dst,
							  UINT32_MAX);
		}
		if (!partial_size) {
			if (data->hw_flow_control) {
				uart_irq_rx_disable(ctx->iface.dev);
			} else {
				LOG_ERR("Rx buffer doesn't have enough space");
				modem_iface_uart_flush(&ctx->iface);
			}
			break;
		}

		rx = uart_fifo_read(ctx->iface.dev, dst, partial_size);
		if (rx <= 0) {
			continue;
		}

		dst += rx;
		total_size += rx;
		partial_size -= rx;
	}

	ret = ring_buf_put_finish(&data->rx_rb, total_size);
	__ASSERT_NO_MSG(ret == 0);

	if (total_size > 0) {
		k_sem_give(&data->rx_sem);
	}
}

static int modem_iface_uart_read(struct modem_iface *iface,
				 uint8_t *buf, size_t size, size_t *bytes_read)
{
	struct modem_iface_uart_data *data;

	if (!iface || !iface->iface_data) {
		return -EINVAL;
	}

	if (size == 0) {
		*bytes_read = 0;
		return 0;
	}

	data = (struct modem_iface_uart_data *)(iface->iface_data);
	*bytes_read = ring_buf_get(&data->rx_rb, buf, size);

	if (data->hw_flow_control && *bytes_read == 0) {
		uart_irq_rx_enable(iface->dev);
	}

	return 0;
}

static bool mux_is_active(struct modem_iface *iface)
{
	bool active = false;

#if defined(CONFIG_UART_MUX_DEVICE_NAME)
	active = strncmp(CONFIG_UART_MUX_DEVICE_NAME, iface->dev->name,
			 sizeof(CONFIG_UART_MUX_DEVICE_NAME) - 1) == 0;
#endif /* CONFIG_UART_MUX_DEVICE_NAME */

	return active;
}

static int modem_iface_uart_write(struct modem_iface *iface,
				  const uint8_t *buf, size_t size)
{
	if (!iface || !iface->iface_data) {
		return -EINVAL;
	}

	if (size == 0) {
		return 0;
	}

	/* If we're using gsm_mux, We don't want to use poll_out because sending
	 * one byte at a time causes each byte to get wrapped in muxing headers.
	 * But we can safely call uart_fifo_fill outside of ISR context when
	 * muxing because uart_mux implements it in software.
	 */
	if (mux_is_active(iface)) {
		uart_fifo_fill(iface->dev, buf, size);
	} else {
		do {
			uart_poll_out(iface->dev, *buf++);
		} while (--size);
	}

	return 0;
}

int modem_iface_uart_init_dev(struct modem_iface *iface,
			      const struct device *dev)
{
	/* get UART device */
	const struct device *prev = iface->dev;

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

	/* Check if there's already a device inited to this iface. If so,
	 * interrupts needs to be disabled on that too before switching to avoid
	 * race conditions with modem_iface_uart_isr.
	 */
	if (prev) {
		uart_irq_tx_disable(prev);
		uart_irq_rx_disable(prev);
	}

	uart_irq_rx_disable(dev);
	uart_irq_tx_disable(dev);
	iface->dev = dev;

	modem_iface_uart_flush(iface);
	uart_irq_callback_set(iface->dev, modem_iface_uart_isr);
	uart_irq_rx_enable(iface->dev);

	if (prev) {
		uart_irq_rx_enable(prev);
	}

	return 0;
}

int modem_iface_uart_init(struct modem_iface *iface,
			  struct modem_iface_uart_data *data,
			  const struct device *dev)
{
	int ret;

	if (!iface || !data) {
		return -EINVAL;
	}

	iface->iface_data = data;
	iface->read = modem_iface_uart_read;
	iface->write = modem_iface_uart_write;

	ring_buf_init(&data->rx_rb, data->rx_rb_buf_len, data->rx_rb_buf);
	k_sem_init(&data->rx_sem, 0, 1);

	/* get UART device */
	ret = modem_iface_uart_init_dev(iface, dev);
	if (ret < 0) {
		iface->iface_data = NULL;
		iface->read = NULL;
		iface->write = NULL;

		return ret;
	}

	return 0;
}
