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

	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)) {
		rx = uart_fifo_read(ctx->iface.dev,
				    data->isr_buf, data->isr_buf_len);
		if (rx <= 0) {
			continue;
		}

		ret = ring_buf_put(&data->rx_rb, data->isr_buf, rx);
		if (ret != rx) {
			LOG_ERR("Rx buffer doesn't have enough space. "
				"Bytes pending: %d, written: %d",
				rx, ret);
			modem_iface_uart_flush(&ctx->iface);
			k_sem_give(&data->rx_sem);
			break;
		}

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

	return 0;
}

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

	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 */
	iface->dev = device_get_binding(dev_name);
	if (!iface->dev) {
		return -ENODEV;
	}

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

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