/** @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 <logging/log.h>
LOG_MODULE_REGISTER(modem_iface_uart, CONFIG_MODEM_LOG_LEVEL);

#include <kernel.h>
#include <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)
	const char *mux_name = CONFIG_UART_MUX_DEVICE_NAME;
	active = (mux_name == iface->dev->name);
#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 char *dev_name)
{
	/* get UART device */
	const struct device *dev = device_get_binding(dev_name);
	const struct device *prev = iface->dev;

	if (!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 char *dev_name)
{
	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_name);
	if (ret < 0) {
		iface->iface_data = NULL;
		iface->read = NULL;
		iface->write = NULL;

		return ret;
	}

	return 0;
}
