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


#include <zephyr/ztest.h>

#include "tests_thread_apis.h"

static ZTEST_BMEM char tp1[8];
static ZTEST_DMEM int tp2 = 100;
static ZTEST_BMEM struct k_sema *tp3;
static ZTEST_BMEM int spawn_prio;

static void thread_entry_params(void *p1, void *p2, void *p3)
{
	/* checkpoint: check parameter 1, 2, 3 */
	zassert_equal(p1, tp1);
	zassert_equal(POINTER_TO_INT(p2), tp2);
	zassert_equal(p3, tp3);
}

static void thread_entry_priority(void *p1, void *p2, void *p3)
{
	/* checkpoint: check priority */
	zassert_equal(k_thread_priority_get(k_current_get()), spawn_prio);
}

static void thread_entry_delay(void *p1, void *p2, void *p3)
{
	tp2 = 100;
}

/* test cases */

/**
 * @ingroup kernel_thread_tests
 * @brief Check the parameters passed to thread entry function
 *
 * @details Create an user thread and pass 2 variables and a
 * semaphore to a thread entry function. Check for the correctness
 * of the parameters passed.
 *
 * @see k_thread_create()
 */
ZTEST_USER(threads_lifecycle, test_threads_spawn_params)
{
	k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_params,
			tp1, INT_TO_POINTER(tp2), tp3, 0,
			K_USER, K_NO_WAIT);
	k_msleep(100);
}

/**
 * @ingroup kernel_thread_tests
 * @brief Spawn thread with higher priority
 *
 * @details Create an user thread with priority greater than
 * current thread and check its behavior.
 *
 * @see k_thread_create()
 */
ZTEST(threads_lifecycle, test_threads_spawn_priority)
{
	/* spawn thread with higher priority */
	spawn_prio = k_thread_priority_get(k_current_get()) - 1;
	k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_priority,
			NULL, NULL, NULL, spawn_prio, K_USER, K_NO_WAIT);
	k_msleep(100);
}

/**
 * @ingroup kernel_thread_tests
 * @brief Spawn thread with a delay
 *
 * @details Create a user thread with delay and check if the
 * thread entry function is executed only after the timeout occurs.
 *
 * @see k_thread_create()
 */
ZTEST_USER(threads_lifecycle, test_threads_spawn_delay)
{
	/* spawn thread with higher priority */
	tp2 = 10;
	k_thread_create(&tdata, tstack, STACK_SIZE, thread_entry_delay,
			NULL, NULL, NULL, 0, K_USER, K_MSEC(120));
	/* 100 < 120 ensure spawn thread not start */
	k_msleep(100);
	/* checkpoint: check spawn thread not execute */
	zassert_true(tp2 == 10);
	/* checkpoint: check spawn thread executed */
	k_msleep(100);
	zassert_true(tp2 == 100);
}

/**
 * @ingroup kernel_thread_tests
 * @brief Spawn thread with forever delay and highest priority
 *
 * @details Create an user thread with forever delay and yield
 * the current thread. Even though the current thread has yielded,
 * the thread will not be put in ready queue since it has forever delay,
 * the thread is explicitly started using k_thread_start() and checked
 * if thread has started executing.
 *
 * @see k_thread_create()
 */
ZTEST(threads_lifecycle, test_threads_spawn_forever)
{
	/* spawn thread with highest priority. It will run immediately once
	 * started.
	 */
	tp2 = 10;
	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
				      thread_entry_delay, NULL, NULL, NULL,
				      K_HIGHEST_THREAD_PRIO,
				      K_USER, K_FOREVER);
	k_yield();
	/* checkpoint: check spawn thread not execute */
	zassert_true(tp2 == 10);
	/* checkpoint: check spawn thread executed */
	k_thread_start(tid);
	k_yield();
	zassert_true(tp2 == 100);
	k_thread_abort(tid);
}

/**
 * @ingroup kernel_thread_tests
 * @brief Validate behavior of multiple calls to k_thread_start()
 *
 * @details Call k_thread_start() on an already terminated thread
 *
 * @see k_thread_start()
 */
ZTEST(threads_lifecycle, test_thread_start)
{
	tp2 = 5;

	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
				      thread_entry_delay, NULL, NULL, NULL,
				      K_HIGHEST_THREAD_PRIO,
				      K_USER, K_FOREVER);

	k_thread_start(tid);
	k_yield();
	zassert_true(tp2 == 100);

	/* checkpoint: k_thread_start() should not start the
	 * terminated thread
	 */

	tp2 = 50;
	k_thread_start(tid);
	k_yield();
	zassert_false(tp2 == 100);
}

static void user_start_thread(void *p1, void *p2, void *p3)
{
	*(int *)p1 = 100;
}
ZTEST_USER(threads_lifecycle, test_thread_start_user)
{
	tp2 = 5;

	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
				      user_start_thread, &tp2, NULL, NULL,
				      0,
				      K_USER, K_FOREVER);

	k_thread_start(tid);
	k_msleep(100);
	zassert_true(tp2 == 100);
	k_thread_abort(tid);
}
