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

#include <zephyr/kernel.h>
#include <zephyr/sys/slist.h>

#include "mock_kernel.h"

/* List of fakes used by this unit tester */
#define FFF_FAKES_LIST(FAKE)                                                                       \
	FAKE(z_timeout_remaining)                                                                  \
	FAKE(k_work_schedule)                                                                      \
	FAKE(k_work_cancel_delayable_sync)                                                         \

/* List of k_work items to be worked. */
static sys_slist_t work_pending;

DEFINE_FAKE_VALUE_FUNC(k_ticks_t, z_timeout_remaining, const struct _timeout *);
DEFINE_FAKE_VALUE_FUNC(int, k_work_schedule, struct k_work_delayable *, k_timeout_t);
DEFINE_FAKE_VALUE_FUNC(bool, k_work_cancel_delayable_sync, struct k_work_delayable *,
		       struct k_work_sync *);
DEFINE_FAKE_VALUE_FUNC(int, k_sem_take, struct k_sem *, k_timeout_t);
DEFINE_FAKE_VOID_FUNC(k_sem_give, struct k_sem *);

void k_work_init_delayable(struct k_work_delayable *dwork, k_work_handler_t handler)
{
	dwork->work.handler = handler;
}

int k_work_reschedule(struct k_work_delayable *dwork, k_timeout_t delay)
{
	struct k_work *work;

	/* Determine whether the work item is queued already. */
	SYS_SLIST_FOR_EACH_CONTAINER(&work_pending, work, node) {
		if (work == &dwork->work) {
			dwork->timeout.dticks = delay.ticks;
			return 0;
		}
	}

	dwork->timeout.dticks = delay.ticks;
	sys_slist_append(&work_pending, &dwork->work.node);

	return 0;
}

int k_work_cancel_delayable(struct k_work_delayable *dwork)
{
	(void)sys_slist_find_and_remove(&work_pending, &dwork->work.node);

	return 0;
}

int32_t k_sleep(k_timeout_t timeout)
{
	struct k_work *work;

	SYS_SLIST_FOR_EACH_CONTAINER(&work_pending, work, node) {
		if (work->flags & K_WORK_DELAYED) {
			struct k_work_delayable *dwork = k_work_delayable_from_work(work);

			if (dwork->timeout.dticks > timeout.ticks) {
				dwork->timeout.dticks -= timeout.ticks;
				continue;
			}
		}

		(void)sys_slist_remove(&work_pending, NULL, &work->node);
		work->handler(work);
	}

	return 0;
}

void mock_kernel_init(void)
{
	FFF_FAKES_LIST(RESET_FAKE);

	sys_slist_init(&work_pending);
}

void mock_kernel_cleanup(void)
{
	struct k_work *work, *tmp;

	/* Run all pending works */
	SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&work_pending, work, tmp, node) {
		(void)sys_slist_remove(&work_pending, NULL, &work->node);
		work->handler(work);
	}
}
