/*
 * Copyright (c) 2016-2017 Nordic Semiconductor ASA
 * Copyright (c) 2016 Vinayak Kariappa Chettimada
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stddef.h>
#include <zephyr/types.h>
#include <misc/printk.h>
#include "memq.h"
#include "mayfly.h"

static struct {
	memq_link_t *head;
	memq_link_t *tail;
	u8_t        enable_req;
	u8_t        enable_ack;
	u8_t        disable_req;
	u8_t        disable_ack;
} mft[MAYFLY_CALLEE_COUNT][MAYFLY_CALLER_COUNT];

static memq_link_t mfl[MAYFLY_CALLEE_COUNT][MAYFLY_CALLER_COUNT];
static u8_t mfp[MAYFLY_CALLEE_COUNT];

#if defined(MAYFLY_UT)
static u8_t _state;
#endif /* MAYFLY_UT */

void mayfly_init(void)
{
	u8_t callee_id;

	callee_id = MAYFLY_CALLEE_COUNT;
	while (callee_id--) {
		u8_t caller_id;

		caller_id = MAYFLY_CALLER_COUNT;
		while (caller_id--) {
			memq_init(&mfl[callee_id][caller_id],
				  &mft[callee_id][caller_id].head,
				  &mft[callee_id][caller_id].tail);
		}
	}
}

void mayfly_enable(u8_t caller_id, u8_t callee_id, u8_t enable)
{
	if (enable) {
		if (mft[callee_id][caller_id].enable_req ==
		    mft[callee_id][caller_id].enable_ack) {
			mft[callee_id][caller_id].enable_req++;
		}

		mayfly_enable_cb(caller_id, callee_id, enable);
	} else {
		if (mft[callee_id][caller_id].disable_req ==
		    mft[callee_id][caller_id].disable_ack) {
			mft[callee_id][caller_id].disable_req++;

			mayfly_pend(caller_id, callee_id);
		}
	}
}

u32_t mayfly_enqueue(u8_t caller_id, u8_t callee_id, u8_t chain,
			struct mayfly *m)
{
	u8_t state;
	u8_t ack;

	chain = chain || !mayfly_prio_is_equal(caller_id, callee_id) ||
		!mayfly_is_enabled(caller_id, callee_id) ||
		(mft[callee_id][caller_id].disable_req !=
		 mft[callee_id][caller_id].disable_ack);

	/* shadow the ack */
	ack = m->_ack;

	/* already in queue */
	state = (m->_req - ack) & 0x03;
	if (state != 0U) {
		if (chain) {
			if (state != 1U) {
				/* mark as ready in queue */
				m->_req = ack + 1;

				goto mayfly_enqueue_pend;
			}

			/* already ready */
			return 1;
		}

		/* mark as done in queue, and fall thru */
		m->_req = ack + 2;
	}

	/* handle mayfly(s) that can be inline */
	if (!chain) {
		/* call fp */
		m->fp(m->param);

		return 0;
	}

	/* new, add as ready in the queue */
	m->_req = ack + 1;
	memq_enqueue(m->_link, m, &mft[callee_id][caller_id].tail);

mayfly_enqueue_pend:
	/* set mayfly callee pending */
	mfp[callee_id] = 1U;

	/* pend the callee for execution */
	mayfly_pend(caller_id, callee_id);

	return 0;
}

static void dequeue(u8_t callee_id, u8_t caller_id, memq_link_t *link,
		    struct mayfly *m)
{
	u8_t req;

	req = m->_req;
	if (((req - m->_ack) & 0x03) != 1U) {
		u8_t ack;

#if defined(MAYFLY_UT)
		u32_t mayfly_ut_run_test(void);
		void mayfly_ut_mfy(void *param);

		if (_state && m->fp == mayfly_ut_mfy) {
			static u8_t single;

			if (!single) {
				single = 1U;
				mayfly_ut_run_test();
			}
		}
#endif /* MAYFLY_UT */

		/* dequeue mayfly struct */
		memq_dequeue(mft[callee_id][caller_id].tail,
			     &mft[callee_id][caller_id].head,
			     0);

		/* release link into dequeued mayfly struct */
		m->_link = link;

		/* reset mayfly state to idle */
		ack = m->_ack;
		m->_ack = req;

		/* re-insert, if re-pended by interrupt */
		if (((m->_req - ack) & 0x03) == 1U) {
#if defined(MAYFLY_UT)
			printk("%s: RACE\n", __func__);
#endif /* MAYFLY_UT */

			m->_ack = ack;
			memq_enqueue(link, m, &mft[callee_id][callee_id].tail);
		}
	}
}

void mayfly_run(u8_t callee_id)
{
	u8_t disable = 0U;
	u8_t enable = 0U;
	u8_t caller_id;

	if (!mfp[callee_id]) {
		return;
	}
	mfp[callee_id] = 1U;

	/* iterate through each caller queue to this callee_id */
	caller_id = MAYFLY_CALLER_COUNT;
	while (caller_id--) {
		memq_link_t *link;
		struct mayfly *m = 0;

		/* fetch mayfly in callee queue, if any */
		link = memq_peek(mft[callee_id][caller_id].head,
				 mft[callee_id][caller_id].tail,
				 (void **)&m);
		while (link) {
			u8_t state;

#if defined(MAYFLY_UT)
			_state = 0U;
#endif /* MAYFLY_UT */

			/* execute work if ready */
			state = (m->_req - m->_ack) & 0x03;
			if (state == 1U) {
#if defined(MAYFLY_UT)
				_state = 1U;
#endif /* MAYFLY_UT */

				/* mark mayfly as ran */
				m->_ack--;

				/* call the mayfly function */
				m->fp(m->param);
			}

			/* dequeue if not re-pended */
			dequeue(callee_id, caller_id, link, m);

			/* fetch next mayfly in callee queue, if any */
			link = memq_peek(mft[callee_id][caller_id].head,
					 mft[callee_id][caller_id].tail,
					 (void **)&m);

			/* yield out of mayfly_run if a mayfly function was
			 * called.
			 */
			if (state == 1U) {
				/* pend callee (tailchain) if mayfly queue is
				 * not empty or all caller queues are not
				 * processed.
				 */
				if (caller_id || link) {
					mayfly_pend(callee_id, callee_id);

					return;
				}
			}
		}

		if (mft[callee_id][caller_id].disable_req !=
		    mft[callee_id][caller_id].disable_ack) {
			disable = 1U;

			mft[callee_id][caller_id].disable_ack =
				mft[callee_id][caller_id].disable_req;
		}

		if (mft[callee_id][caller_id].enable_req !=
		    mft[callee_id][caller_id].enable_ack) {
			enable = 1U;

			mft[callee_id][caller_id].enable_ack =
				mft[callee_id][caller_id].enable_req;
		}
	}

	if (disable && !enable) {
		mayfly_enable_cb(callee_id, callee_id, 0);
	}
}

#if defined(MAYFLY_UT)
#define MAYFLY_CALL_ID_CALLER MAYFLY_CALL_ID_0
#define MAYFLY_CALL_ID_CALLEE MAYFLY_CALL_ID_2

void mayfly_ut_mfy(void *param)
{
	printk("%s: ran.\n", __func__);

	(*((u32_t *)param))++;
}

void mayfly_ut_test(void *param)
{
	static u32_t *count;
	static memq_link_t link;
	static struct mayfly mfy = {0, 0, &link, NULL, mayfly_ut_mfy};
	u32_t err;

	printk("%s: req= %u, ack= %u\n", __func__, mfy._req, mfy._ack);

	if (param) {
		count = param;
	}

	mfy.param = count;

	err = mayfly_enqueue(MAYFLY_CALL_ID_CALLER, MAYFLY_CALL_ID_CALLEE, 1,
			     &mfy);
	if (err) {
		printk("%s: FAILED (%u).\n", __func__, err);
	} else {
		printk("%s: SUCCESS.\n", __func__);
	}
}

u32_t mayfly_ut_run_test(void)
{
	static memq_link_t link;
	static struct mayfly mfy = {0, 0, &link, NULL, mayfly_ut_test};
	u32_t err;

	printk("%s: req= %u, ack= %u\n", __func__, mfy._req, mfy._ack);

	err = mayfly_enqueue(MAYFLY_CALL_ID_CALLEE, MAYFLY_CALL_ID_CALLER, 0,
			     &mfy);

	if (err) {
		printk("%s: FAILED.\n", __func__);
		return err;
	}

	printk("%s: SUCCESS.\n", __func__);

	return 0;
}

u32_t mayfly_ut(void)
{
	static u32_t count;
	static memq_link_t link;
	static struct mayfly mfy = {0, 0, &link, &count, mayfly_ut_test};
	u32_t err;

	printk("%s: req= %u, ack= %u\n", __func__, mfy._req, mfy._ack);

	err = mayfly_enqueue(MAYFLY_CALL_ID_PROGRAM, MAYFLY_CALL_ID_CALLER, 0,
			     &mfy);

	if (err) {
		printk("%s: FAILED.\n", __func__);
		return err;
	}

	printk("%s: count = %u.\n", __func__, count);
	printk("%s: SUCCESS.\n", __func__);
	return 0;
}
#endif /* MAYFLY_UT */
