/*
 * Copyright (c) 2022 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/ztest.h>
#include <zephyr/rtio/rtio_mpsc.h>
#include <zephyr/rtio/rtio.h>
#include <zephyr/kernel.h>

#ifndef RTIO_IODEV_TEST_H_
#define RTIO_IODEV_TEST_H_

struct rtio_iodev_test_data {
	/* k_timer for an asynchronous task */
	struct k_timer timer;

	/* Currently executing sqe */
	struct rtio_iodev_sqe *txn_head;
	struct rtio_iodev_sqe *txn_curr;

	/* Count of submit calls */
	atomic_t submit_count;

	/* Lock around kicking off next timer */
	struct k_spinlock lock;
};

static void rtio_iodev_test_next(struct rtio_iodev *iodev)
{
	struct rtio_iodev_test_data *data = iodev->data;

	/* The next section must be serialized to ensure single consumer semantics */
	k_spinlock_key_t key = k_spin_lock(&data->lock);

	if (data->txn_head != NULL) {
		goto out;
	}

	struct rtio_mpsc_node *next = rtio_mpsc_pop(&iodev->iodev_sq);

	if (next != NULL) {
		struct rtio_iodev_sqe *next_sqe = CONTAINER_OF(next, struct rtio_iodev_sqe, q);

		TC_PRINT("next task in queue %p\n", (void *)next_sqe);

		data->txn_head = next_sqe;
		data->txn_curr = next_sqe;
		k_timer_start(&data->timer, K_MSEC(10), K_NO_WAIT);
	} else {
		TC_PRINT("no more tasks in the queue\n");
	}

out:
	k_spin_unlock(&data->lock, key);
}

static void rtio_iodev_timer_fn(struct k_timer *tm)
{
	static struct rtio_iodev_sqe *last_iodev_sqe;
	static int consecutive_sqes;

	struct rtio_iodev_test_data *data = CONTAINER_OF(tm, struct rtio_iodev_test_data, timer);
	struct rtio_iodev_sqe *iodev_sqe = data->txn_curr;
	struct rtio_iodev *iodev = (struct rtio_iodev *)data->txn_head->sqe.iodev;

	if (iodev_sqe == last_iodev_sqe) {
		consecutive_sqes++;
	} else {
		consecutive_sqes = 0;
	}
	last_iodev_sqe = iodev_sqe;

	if (iodev_sqe->sqe.op == RTIO_OP_RX) {
		uint8_t *buf;
		uint32_t buf_len;

		int rc = rtio_sqe_rx_buf(iodev_sqe, 16, 16, &buf, &buf_len);

		if (rc != 0) {
			iodev_sqe = data->txn_head;
			data->txn_head = NULL;
			data->txn_curr = NULL;
			rtio_iodev_sqe_err(iodev_sqe, rc);
			rtio_iodev_test_next(iodev);
			return;
		}

		for (int i = 0; i < 16; ++i) {
			buf[i] = ((uint8_t *)iodev_sqe->sqe.userdata)[i];
		}
	}

	if (iodev_sqe->sqe.flags & RTIO_SQE_TRANSACTION) {
		data->txn_curr = rtio_txn_next(data->txn_curr);
		TC_PRINT("iodev_sqe %p marked transaction, next %p\n", iodev_sqe, data->txn_curr);
		k_timer_start(tm, K_MSEC(10), K_NO_WAIT);
		return;
	}

	iodev_sqe = data->txn_head;
	data->txn_head = NULL;
	data->txn_curr = NULL;
	rtio_iodev_test_next(iodev);
	if (consecutive_sqes == 0) {
		rtio_iodev_sqe_ok(iodev_sqe, 0);
	} else {
		rtio_iodev_sqe_err(iodev_sqe, consecutive_sqes);
	}
}

static void rtio_iodev_test_submit(struct rtio_iodev_sqe *iodev_sqe)
{
	struct rtio_iodev *iodev = (struct rtio_iodev *)iodev_sqe->sqe.iodev;
	struct rtio_iodev_test_data *data = iodev->data;

	atomic_inc(&data->submit_count);

	/* The only safe operation is enqueuing */
	rtio_mpsc_push(&iodev->iodev_sq, &iodev_sqe->q);

	rtio_iodev_test_next(iodev);
}

const struct rtio_iodev_api rtio_iodev_test_api = {
	.submit = rtio_iodev_test_submit,
};

void rtio_iodev_test_init(struct rtio_iodev *test)
{
	struct rtio_iodev_test_data *data = test->data;

	rtio_mpsc_init(&test->iodev_sq);
	data->txn_head = NULL;
	data->txn_curr = NULL;
	k_timer_init(&data->timer, rtio_iodev_timer_fn, NULL);
}

#define RTIO_IODEV_TEST_DEFINE(name)                                                               \
	static struct rtio_iodev_test_data _iodev_data_##name;                                     \
	RTIO_IODEV_DEFINE(name, &rtio_iodev_test_api, &_iodev_data_##name)



#endif /* RTIO_IODEV_TEST_H_ */
