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

#include <string.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/drivers/serial/uart_async_rx.h>

static uint8_t inc(struct uart_async_rx *rx_data, uint8_t val)
{
	return (val + 1) & (rx_data->config->buf_cnt - 1);
}

static struct uart_async_rx_buf *get_buf(struct uart_async_rx *rx_data, uint8_t idx)
{
	uint8_t *p = rx_data->config->buffer;

	p += idx * (rx_data->buf_len + sizeof(struct uart_async_rx_buf));

	return (struct uart_async_rx_buf *)p;
}

uint8_t *uart_async_rx_buf_req(struct uart_async_rx *rx_data)
{
	uint8_t *data = NULL;

	if (rx_data->free_buf_cnt != 0) {
		struct uart_async_rx_buf *buf = get_buf(rx_data, rx_data->drv_buf_idx);

		data = buf->buffer;
		rx_data->drv_buf_idx = inc(rx_data, rx_data->drv_buf_idx);

		atomic_dec(&rx_data->free_buf_cnt);
	}

	return data;
}

void uart_async_rx_on_rdy(struct uart_async_rx *rx_data, uint8_t *buffer, size_t length)
{
	/* Cannot use CONTAINER_OF because validation fails due to type mismatch:
	 * uint8_t * vs uint8_t [].
	 */
	struct uart_async_rx_buf *rx_buf =
		(struct uart_async_rx_buf *)(buffer - offsetof(struct uart_async_rx_buf, buffer));

	rx_buf->wr_idx += length;
	__ASSERT_NO_MSG(rx_buf->wr_idx <= rx_data->buf_len);

	atomic_add(&rx_data->pending_bytes, length);
}

static void buf_reset(struct uart_async_rx_buf *buf)
{
	buf->rd_idx = 0;
	buf->wr_idx = 0;
	buf->completed = 0;
}
static void usr_rx_buf_release(struct uart_async_rx *rx_data, struct uart_async_rx_buf *buf)
{
	buf_reset(buf);
	rx_data->rd_buf_idx = inc(rx_data, rx_data->rd_buf_idx);
	atomic_inc(&rx_data->free_buf_cnt);
	__ASSERT_NO_MSG(rx_data->free_buf_cnt <= rx_data->config->buf_cnt);
}

void uart_async_rx_on_buf_rel(struct uart_async_rx *rx_data, uint8_t *buffer)
{
	/* Cannot use CONTAINER_OF because validation fails due to type mismatch:
	 * uint8_t * vs uint8_t [].
	 */
	struct uart_async_rx_buf *rx_buf =
		(struct uart_async_rx_buf *)(buffer - offsetof(struct uart_async_rx_buf, buffer));

	rx_buf->completed = 1;
	rx_data->wr_buf_idx = inc(rx_data, rx_data->wr_buf_idx);
}

size_t uart_async_rx_data_claim(struct uart_async_rx *rx_data, uint8_t **data, size_t length)
{
	struct uart_async_rx_buf *buf;
	int rem;

	if ((rx_data->pending_bytes == 0) || (length == 0)) {
		return 0;
	}

	do {
		buf = get_buf(rx_data, rx_data->rd_buf_idx);
		if ((buf->rd_idx == buf->wr_idx) && (buf->completed == 1)) {
			usr_rx_buf_release(rx_data, buf);
		} else {
			break;
		}
	} while (1);

	*data = &buf->buffer[buf->rd_idx];
	rem = buf->wr_idx - buf->rd_idx;

	return MIN(length, rem);
}

void uart_async_rx_data_consume(struct uart_async_rx *rx_data, size_t length)
{
	struct uart_async_rx_buf *buf = get_buf(rx_data, rx_data->rd_buf_idx);

	buf->rd_idx += length;

	atomic_sub(&rx_data->pending_bytes, length);

	__ASSERT_NO_MSG(buf->rd_idx <= buf->wr_idx);
}

void uart_async_rx_reset(struct uart_async_rx *rx_data)
{
	rx_data->free_buf_cnt = rx_data->config->buf_cnt;
	for (uint8_t i = 0; i < rx_data->config->buf_cnt; i++) {
		buf_reset(get_buf(rx_data, i));
	}
}

int uart_async_rx_init(struct uart_async_rx *rx_data,
		       const struct uart_async_rx_config *config)
{
	__ASSERT_NO_MSG(config->length / config->buf_cnt <= UINT8_MAX);
	memset(rx_data, 0, sizeof(*rx_data));
	rx_data->config = config;
	rx_data->buf_len = (config->length / config->buf_cnt) - UART_ASYNC_RX_BUF_OVERHEAD;
	uart_async_rx_reset(rx_data);

	return 0;
}
