/*
 * Copyright (c) 2016 Wind River Systems, Inc.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/tc_util.h>
#include <zephyr/ztest.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/sys/util.h>
#include <zephyr/irq_offload.h>
#include <stdbool.h>

#if defined(CONFIG_ASSERT) && defined(CONFIG_DEBUG)
#define THREAD_STACK    (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
#else
#define THREAD_STACK    (384 + CONFIG_TEST_EXTRA_STACK_SIZE)
#endif

#define TEST_THREAD_PRIORITY    -4
#define HELPER_THREAD_PRIORITY  -10

#define ONE_SECOND		(MSEC_PER_SEC)
#define ONE_SECOND_ALIGNED	\
	(uint32_t)(k_ticks_to_ms_floor64(k_ms_to_ticks_ceil32(ONE_SECOND) + _TICK_ALIGN))

#if defined(CONFIG_SOC_XILINX_ZYNQMP)
/*
 * The Xilinx QEMU, used to emulate the Xilinx ZynqMP platform, is particularly
 * unstable in terms of timing. The tick margin of at least 5 is necessary to
 * allow this test to pass with a reasonable repeatability.
 */
#define TICK_MARGIN		5
#else
#define TICK_MARGIN		1
#endif

static struct k_sem test_thread_sem;
static struct k_sem helper_thread_sem;
static struct k_sem task_sem;

static K_THREAD_STACK_DEFINE(test_thread_stack, THREAD_STACK);
static K_THREAD_STACK_DEFINE(helper_thread_stack, THREAD_STACK);

static k_tid_t test_thread_id;
static k_tid_t helper_thread_id;

static struct k_thread test_thread_data;
static struct k_thread helper_thread_data;

static bool test_failure = true;     /* Assume the test will fail */

/**
 * @brief Test sleep and wakeup APIs
 *
 * @defgroup kernel_sleep_tests Sleep Tests
 *
 * @ingroup all_tests
 *
 * This module tests the following sleep and wakeup scenarios:
 * 1. k_sleep() without cancellation
 * 2. k_sleep() cancelled via k_wakeup()
 * 3. k_sleep() cancelled via k_wakeup()
 * 4. k_sleep() cancelled via k_wakeup()
 * 5. k_sleep() - no cancellation exists
 *
 * @{
 * @}
 */
static void test_objects_init(void)
{
	k_sem_init(&test_thread_sem, 0, UINT_MAX);
	k_sem_init(&helper_thread_sem, 0, UINT_MAX);
	k_sem_init(&task_sem, 0, UINT_MAX);

	TC_PRINT("Kernel objects initialized\n");
}

static void align_to_tick_boundary(void)
{
	uint32_t tick;

	tick = k_uptime_get_32();
	while (k_uptime_get_32() == tick) {
		/* Busy wait to align to tick boundary */
		Z_SPIN_DELAY(50);
	}

}

/* Shouldn't ever sleep for less than requested time, but allow for 1
 * tick of "too long" slop for aliasing between wakeup and
 * measurement. Qemu at least will leak the external world's clock
 * rate into the simulator when the host is under load.
 */
static int sleep_time_valid(uint32_t start, uint32_t end, uint32_t dur)
{
	uint32_t dt = end - start;

	return dt >= dur && dt <= (dur + TICK_MARGIN);
}

static void test_thread(void *p1, void *p2, void *p3)
{
	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	uint32_t start_tick;
	uint32_t end_tick;

	k_sem_take(&test_thread_sem, K_FOREVER);

	TC_PRINT("Testing normal expiration of k_sleep()\n");
	align_to_tick_boundary();

	start_tick = k_uptime_get_32();
	k_sleep(K_SECONDS(1));
	end_tick = k_uptime_get_32();

	if (!sleep_time_valid(start_tick, end_tick, ONE_SECOND_ALIGNED)) {
		TC_ERROR(" *** k_sleep() slept for %d ticks not %d.",
			 end_tick - start_tick, ONE_SECOND_ALIGNED);

		return;
	}

	TC_PRINT("Testing: test thread sleep + helper thread wakeup test\n");
	k_sem_give(&helper_thread_sem);   /* Activate helper thread */
	align_to_tick_boundary();

	start_tick = k_uptime_get_32();
	k_sleep(K_SECONDS(1));
	end_tick = k_uptime_get_32();

	if (end_tick - start_tick > TICK_MARGIN) {
		TC_ERROR(" *** k_wakeup() took too long (%d ticks)\n",
			 end_tick - start_tick);
		return;
	}

	TC_PRINT("Testing: test thread sleep + isr offload wakeup test\n");
	k_sem_give(&helper_thread_sem);   /* Activate helper thread */
	align_to_tick_boundary();

	start_tick = k_uptime_get_32();
	k_sleep(K_SECONDS(1));
	end_tick = k_uptime_get_32();

	if (end_tick - start_tick > TICK_MARGIN) {
		TC_ERROR(" *** k_wakeup() took too long (%d ticks)\n",
			 end_tick - start_tick);
		return;
	}

	TC_PRINT("Testing: test thread sleep + main wakeup test thread\n");
	k_sem_give(&task_sem);    /* Activate task */
	align_to_tick_boundary();

	start_tick = k_uptime_get_32();
	k_sleep(K_SECONDS(1));	/* Task will execute */
	end_tick = k_uptime_get_32();

	if (end_tick - start_tick > TICK_MARGIN) {
		TC_ERROR(" *** k_wakeup() took too long (%d ticks) at LAST\n",
			 end_tick - start_tick);
		return;
	}
	test_failure = false;
}

static void irq_offload_isr(const void *arg)
{

	k_wakeup((k_tid_t) arg);
}

static void helper_thread(void *p1, void *p2, void *p3)
{
	ARG_UNUSED(p1);
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	k_sem_take(&helper_thread_sem, K_FOREVER);
	/* Wake the test thread */
	k_wakeup(test_thread_id);
	k_sem_take(&helper_thread_sem, K_FOREVER);
	/* Wake the test thread from an ISR */
	irq_offload(irq_offload_isr, (const void *)test_thread_id);
}

/**
 * @brief Test sleep functionality
 *
 * @ingroup kernel_sleep_tests
 *
 * @see k_sleep(), k_wakeup(), k_uptime_get_32()
 */
ZTEST(sleep, test_sleep)
{
	int status = TC_FAIL;
	uint32_t start_tick;
	uint32_t end_tick;

	/*
	 * Main thread(test_main) priority is 0 but ztest thread runs at
	 * priority -1. To run the test smoothly make both main and ztest
	 * threads run at same priority level.
	 */
	k_thread_priority_set(k_current_get(), 0);
	test_objects_init();

	test_thread_id = k_thread_create(&test_thread_data, test_thread_stack,
					 THREAD_STACK,
					 test_thread,
					 0, 0, NULL, TEST_THREAD_PRIORITY,
					 0, K_NO_WAIT);

	TC_PRINT("Test thread started: id = %p\n", test_thread_id);

	helper_thread_id = k_thread_create(&helper_thread_data,
					   helper_thread_stack, THREAD_STACK,
					   helper_thread,
					   0, 0, NULL, HELPER_THREAD_PRIORITY,
					   0, K_NO_WAIT);

	TC_PRINT("Helper thread started: id = %p\n", helper_thread_id);

	/* Activate test_thread */
	k_sem_give(&test_thread_sem);

	/* Wait for test_thread to activate us */
	k_sem_take(&task_sem, K_FOREVER);

	/* Wake the test thread */
	k_wakeup(test_thread_id);

	zassert_false(test_failure, "test failure");

	TC_PRINT("Testing kernel k_sleep()\n");
	align_to_tick_boundary();
	start_tick = k_uptime_get_32();
	k_sleep(K_SECONDS(1));
	end_tick = k_uptime_get_32();
	zassert_true(sleep_time_valid(start_tick, end_tick, ONE_SECOND_ALIGNED),
		     "k_sleep() slept for %d ticks, not %d\n",
		     end_tick - start_tick, ONE_SECOND_ALIGNED);

	status = TC_PASS;
}

static void forever_thread_entry(void *p1, void *p2, void *p3)
{
	int32_t ret;

	ret = k_sleep(K_FOREVER);
	zassert_equal(ret, K_TICKS_FOREVER, "unexpected return value");
	k_sem_give(&test_thread_sem);
}

ZTEST(sleep, test_sleep_forever)
{
	test_objects_init();

	test_thread_id = k_thread_create(&test_thread_data,
					 test_thread_stack,
					 THREAD_STACK,
					 forever_thread_entry,
					 0, 0, NULL, TEST_THREAD_PRIORITY,
					 K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	/* Allow forever thread to run */
	k_yield();

	k_wakeup(test_thread_id);
	k_sem_take(&test_thread_sem, K_FOREVER);
}

/*test case main entry*/
static void *sleep_setup(void)
{
	k_thread_access_grant(k_current_get(), &test_thread_sem);

	return NULL;
}

ZTEST_SUITE(sleep, NULL, sleep_setup,
		ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
