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


/**
 * @brief Thread Tests
 * @defgroup kernel_thread_tests Threads
 * @ingroup all_tests
 * @{
 * @}
 */

#include <zephyr/ztest.h>
#include <zephyr/kernel_structs.h>
#include <zephyr/kernel.h>
#include <kernel_internal.h>
#include <string.h>

/* internal kernel APIs */
#include <ksched.h>
#include <kthread.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(test);

struct k_thread tdata;
#define STACK_SIZE (512 + CONFIG_TEST_EXTRA_STACK_SIZE)
K_THREAD_STACK_DEFINE(tstack, STACK_SIZE);
size_t tstack_size = K_THREAD_STACK_SIZEOF(tstack);

/*local variables*/
static K_THREAD_STACK_DEFINE(tstack_custom, STACK_SIZE);
static K_THREAD_STACK_DEFINE(tstack_name, STACK_SIZE);
static struct k_thread tdata_custom;
static struct k_thread tdata_name;

static int main_prio;
static ZTEST_DMEM int tp = 10;

/**
 * @ingroup kernel_thread_tests
 * @brief Verify main thread
 */
ZTEST(threads_lifecycle, test_systhreads_main)
{
	zassert_true(main_prio == CONFIG_MAIN_THREAD_PRIORITY, "%d", CONFIG_MAIN_THREAD_PRIORITY);
}

/**
 * @ingroup kernel_thread_tests
 * @brief Verify idle thread
 */
ZTEST(threads_lifecycle, test_systhreads_idle)
{
	k_msleep(100);
	/** TESTPOINT: check working thread priority should */
	zassert_true(k_thread_priority_get(k_current_get()) <
		     K_IDLE_PRIO, NULL);
}

static void customdata_entry(void *p1, void *p2, void *p3)
{
	long data = 1U;

	zassert_is_null(k_thread_custom_data_get(), NULL);
	while (1) {
		k_thread_custom_data_set((void *)data);
		/* relinquish cpu for a while */
		k_msleep(50);
		/** TESTPOINT: custom data comparison */
		zassert_equal(data, (long)k_thread_custom_data_get());
		data++;
	}
}

/**
 * @ingroup kernel_thread_tests
 * @brief test thread custom data get/set from coop thread
 *
 * @see k_thread_custom_data_get(), k_thread_custom_data_set()
 */
ZTEST(threads_lifecycle_1cpu, test_customdata_get_set_coop)
{
	k_tid_t tid = k_thread_create(&tdata_custom, tstack_custom, STACK_SIZE,
				      customdata_entry, NULL, NULL, NULL,
				      K_PRIO_COOP(1), 0, K_NO_WAIT);

	k_msleep(500);

	/* cleanup environment */
	k_thread_abort(tid);
}

static void thread_name_entry(void *p1, void *p2, void *p3)
{
	/* Do nothing and exit */
}

/**
 * @ingroup kernel_thread_tests
 * @brief test thread name get/set from supervisor thread
 * @see k_thread_name_get(), k_thread_name_copy(), k_thread_name_set()
 */
ZTEST(threads_lifecycle, test_thread_name_get_set)
{
	int ret;
	const char *thread_name;
	char thread_buf[CONFIG_THREAD_MAX_NAME_LEN];

	/* Set and get current thread's name */
	ret = k_thread_name_set(NULL, "parent_thread");
	zassert_equal(ret, 0, "k_thread_name_set() failed");
	thread_name = k_thread_name_get(k_current_get());
	zassert_true(thread_name != NULL, "thread name was null");
	ret = strcmp(thread_name, "parent_thread");
	zassert_equal(ret, 0, "parent thread name does not match");

	/* Set and get child thread's name */
	k_tid_t tid = k_thread_create(&tdata_name, tstack_name, STACK_SIZE,
				      thread_name_entry, NULL, NULL, NULL,
				      K_PRIO_PREEMPT(1), 0, K_NO_WAIT);

	ret = k_thread_name_set(tid, "customdata");
	zassert_equal(ret, 0, "k_thread_name_set() failed");
	ret = k_thread_name_copy(tid, thread_buf, sizeof(thread_buf));
	zassert_equal(ret, 0, "couldn't get copied thread name");
	ret = strcmp(thread_buf, "customdata");
	zassert_equal(ret, 0, "child thread name does not match");

	/* cleanup environment */
	k_thread_abort(tid);
}

#ifdef CONFIG_USERSPACE
static char unreadable_string[64];
static char not_my_buffer[CONFIG_THREAD_MAX_NAME_LEN];
struct k_sem sem;
#endif /* CONFIG_USERSPACE */

/**
 * @ingroup kernel_thread_tests
 * @brief test thread name get/set from user thread
 * @see k_thread_name_copy(), k_thread_name_set()
 */
ZTEST_USER(threads_lifecycle, test_thread_name_user_get_set)
{
#ifdef CONFIG_USERSPACE
	int ret;
	char thread_name[CONFIG_THREAD_MAX_NAME_LEN];
	char too_small[2];

	/* Some memory-related error cases for k_thread_name_set() */
#if !defined(CONFIG_TRUSTED_EXECUTION_NONSECURE)
	/* Non-Secure images cannot normally access memory outside the image
	 * flash and ram.
	 */
	ret = k_thread_name_set(NULL, (const char *)0xFFFFFFF0);
	zassert_equal(ret, -EFAULT, "accepted nonsense string (%d)", ret);
#endif
	ret = k_thread_name_set(NULL, unreadable_string);
	zassert_equal(ret, -EFAULT, "accepted unreadable string");
	ret = k_thread_name_set((struct k_thread *)&sem, "some name");
	zassert_equal(ret, -EINVAL, "accepted non-thread object");
	ret = k_thread_name_set(&z_main_thread, "some name");
	zassert_equal(ret, -EINVAL, "no permission on thread object");

	/* Set and get current thread's name */
	ret = k_thread_name_set(NULL, "parent_thread");
	zassert_equal(ret, 0, "k_thread_name_set() failed");
	ret = k_thread_name_copy(k_current_get(), thread_name,
				     sizeof(thread_name));
	zassert_equal(ret, 0, "k_thread_name_copy() failed");
	ret = strcmp(thread_name, "parent_thread");
	zassert_equal(ret, 0, "parent thread name does not match");

	/* memory-related cases for k_thread_name_get() */
	ret = k_thread_name_copy(k_current_get(), too_small,
				     sizeof(too_small));
	zassert_equal(ret, -ENOSPC, "wrote to too-small buffer");
	ret = k_thread_name_copy(k_current_get(), not_my_buffer,
				     sizeof(not_my_buffer));
	zassert_equal(ret, -EFAULT, "wrote to buffer without permission");
	ret = k_thread_name_copy((struct k_thread *)&sem, thread_name,
				     sizeof(thread_name));
	zassert_equal(ret, -EINVAL, "not a thread object");
	ret = k_thread_name_copy(&z_main_thread, thread_name,
				     sizeof(thread_name));
	zassert_equal(ret, 0, "couldn't get main thread name: %s (%d)", thread_name, ret);
	LOG_DBG("Main thread name is '%s'", thread_name);

	/* Set and get child thread's name */
	k_tid_t tid = k_thread_create(&tdata_name, tstack_name, STACK_SIZE,
				      thread_name_entry, NULL, NULL, NULL,
				      K_PRIO_PREEMPT(1), K_USER, K_NO_WAIT);
	ret = k_thread_name_set(tid, "customdata");
	zassert_equal(ret, 0, "k_thread_name_set() failed");
	ret = k_thread_name_copy(tid, thread_name, sizeof(thread_name));
	zassert_equal(ret, 0, "couldn't get copied thread name");
	ret = strcmp(thread_name, "customdata");
	zassert_equal(ret, 0, "child thread name does not match");

	/* cleanup environment */
	k_thread_abort(tid);
#else
	ztest_test_skip();
#endif /* CONFIG_USERSPACE */
}

/**
 * @ingroup kernel_thread_tests
 * @brief test thread custom data get/set from preempt thread
 * @see k_thread_custom_data_get(), k_thread_custom_data_set()
 */
ZTEST_USER(threads_lifecycle_1cpu, test_customdata_get_set_preempt)
{
	/** TESTPOINT: custom data of preempt thread */
	k_tid_t tid = k_thread_create(&tdata_custom, tstack_custom, STACK_SIZE,
				      customdata_entry, NULL, NULL, NULL,
				      K_PRIO_PREEMPT(0), K_USER, K_NO_WAIT);

	k_msleep(500);

	/* cleanup environment */
	k_thread_abort(tid);
}

static void umode_entry(void *thread_id, void *p2, void *p3)
{
	ARG_UNUSED(p2);
	ARG_UNUSED(p3);

	if (!z_is_thread_essential(_current) &&
	    (k_current_get() == (k_tid_t)thread_id)) {
		ztest_test_pass();
	} else {
		zassert_unreachable("User thread is essential or thread"
				    " structure is corrupted\n");
	}
}

/**
 * @ingroup kernel_thread_tests
 * @brief Test k_thread_user_mode_enter() to cover when userspace
 * is not supported/enabled
 * @see k_thread_user_mode_enter()
 */
static void enter_user_mode_entry(void *p1, void *p2, void *p3)
{
	z_thread_essential_set(_current);

	zassert_true(z_is_thread_essential(_current), "Thread isn't set"
		     " as essential\n");

	k_thread_user_mode_enter(umode_entry,
				 k_current_get(), NULL, NULL);
}

ZTEST_USER(threads_lifecycle, test_user_mode)
{
	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
			      enter_user_mode_entry, NULL, NULL,
			      NULL, main_prio, K_INHERIT_PERMS, K_NO_WAIT);
	k_msleep(100);
	k_thread_abort(tid);
}

struct k_thread join_thread;
K_THREAD_STACK_DEFINE(join_stack, STACK_SIZE);

struct k_thread control_thread;
K_THREAD_STACK_DEFINE(control_stack, STACK_SIZE);

enum control_method {
	TIMEOUT,
	NO_WAIT,
	SELF_ABORT,
	OTHER_ABORT,
	OTHER_ABORT_TIMEOUT,
	ALREADY_EXIT,
	ISR_ALREADY_EXIT,
	ISR_RUNNING
};

static void join_entry(void *p1, void *p2, void *p3)
{
	enum control_method m = (enum control_method)(intptr_t)p1;

	switch (m) {
	case TIMEOUT:
	case NO_WAIT:
	case OTHER_ABORT:
	case OTHER_ABORT_TIMEOUT:
	case ISR_RUNNING:
		LOG_DBG("join_thread: sleeping forever");
		k_sleep(K_FOREVER);
		break;
	case SELF_ABORT:
	case ALREADY_EXIT:
	case ISR_ALREADY_EXIT:
		LOG_DBG("join_thread: self-exiting");
		return;
	}
}

static void control_entry(void *p1, void *p2, void *p3)
{
	LOG_DBG("control_thread: killing join thread");
	k_thread_abort(&join_thread);
}

static void do_join_from_isr(const void *arg)
{
	int *ret = (int *)arg;

	zassert_true(k_is_in_isr());
	LOG_DBG("isr: joining join_thread");
	*ret = k_thread_join(&join_thread, K_NO_WAIT);
	LOG_DBG("isr: k_thread_join() returned with %d", *ret);
}

#define JOIN_TIMEOUT_MS	100

static int join_scenario_interval(enum control_method m, int64_t *interval)
{
	k_timeout_t timeout = K_FOREVER;
	int ret;

	LOG_DBG("ztest_thread: method %d, create join_thread", m);
	k_thread_create(&join_thread, join_stack, STACK_SIZE, join_entry,
			(void *)m, NULL, NULL, K_PRIO_PREEMPT(1),
			K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	switch (m) {
	case ALREADY_EXIT:
	case ISR_ALREADY_EXIT:
		/* Let join_thread run first */
		k_msleep(50);
		break;
	case OTHER_ABORT_TIMEOUT:
		timeout = K_MSEC(JOIN_TIMEOUT_MS);
		__fallthrough;
	case OTHER_ABORT:
		LOG_DBG("ztest_thread: create control_thread");
		k_thread_create(&control_thread, control_stack, STACK_SIZE,
				control_entry, NULL, NULL, NULL,
				K_PRIO_PREEMPT(2),
				K_USER | K_INHERIT_PERMS, K_NO_WAIT);
		break;
	case TIMEOUT:
		timeout = K_MSEC(50);
		break;
	case NO_WAIT:
		timeout = K_NO_WAIT;
		break;
	default:
		break;
	}

	if (m == ISR_ALREADY_EXIT || m == ISR_RUNNING) {
		irq_offload(do_join_from_isr, (const void *)&ret);
	} else {
		LOG_DBG("ztest_thread: joining join_thread");

		if (interval != NULL) {
			*interval = k_uptime_get();
		}

		ret = k_thread_join(&join_thread, timeout);

		if (interval != NULL) {
			*interval = k_uptime_get() - *interval;
		}

		LOG_DBG("ztest_thread: k_thread_join() returned with %d", ret);
	}

	if (ret != 0) {
		k_thread_abort(&join_thread);
	}
	if (m == OTHER_ABORT || m == OTHER_ABORT_TIMEOUT) {
		k_thread_join(&control_thread, K_FOREVER);
	}

	return ret;
}

static inline int join_scenario(enum control_method m)
{
	return join_scenario_interval(m, NULL);
}

ZTEST_USER(threads_lifecycle, test_thread_join)
{
	int64_t interval;

#ifdef CONFIG_USERSPACE
	/* scenario: thread never started */
	zassert_equal(k_thread_join(&join_thread, K_FOREVER), 0,
		      "failed case thread never started");
#endif
	zassert_equal(join_scenario(TIMEOUT), -EAGAIN, "failed timeout case");
	zassert_equal(join_scenario(NO_WAIT), -EBUSY, "failed no-wait case");
	zassert_equal(join_scenario(SELF_ABORT), 0, "failed self-abort case");
	zassert_equal(join_scenario(OTHER_ABORT), 0, "failed other-abort case");

	zassert_equal(join_scenario_interval(OTHER_ABORT_TIMEOUT, &interval),
		      0, "failed other-abort case with timeout");
	zassert_true(interval < JOIN_TIMEOUT_MS, "join took too long (%lld ms)",
		     interval);
	zassert_equal(join_scenario(ALREADY_EXIT), 0,
		      "failed already exit case");

}

ZTEST(threads_lifecycle, test_thread_join_isr)
{
	zassert_equal(join_scenario(ISR_RUNNING), -EBUSY, "failed isr running");
	zassert_equal(join_scenario(ISR_ALREADY_EXIT), 0, "failed isr exited");
}

struct k_thread deadlock1_thread;
K_THREAD_STACK_DEFINE(deadlock1_stack, STACK_SIZE);

struct k_thread deadlock2_thread;
K_THREAD_STACK_DEFINE(deadlock2_stack, STACK_SIZE);

static void deadlock1_entry(void *p1, void *p2, void *p3)
{
	int ret;

	k_msleep(500);

	ret = k_thread_join(&deadlock2_thread, K_FOREVER);
	zassert_equal(ret, -EDEADLK, "failed mutual join case");
}

static void deadlock2_entry(void *p1, void *p2, void *p3)
{
	int ret;

	/* deadlock1_thread is active but currently sleeping */
	ret = k_thread_join(&deadlock1_thread, K_FOREVER);

	zassert_equal(ret, 0, "couldn't join deadlock2_thread");
}

ZTEST_USER(threads_lifecycle, test_thread_join_deadlock)
{
	/* Deadlock scenarios */
	zassert_equal(k_thread_join(k_current_get(), K_FOREVER), -EDEADLK,
				    "failed self-deadlock case");

	k_thread_create(&deadlock1_thread, deadlock1_stack, STACK_SIZE,
			deadlock1_entry, NULL, NULL, NULL,
			K_PRIO_PREEMPT(1), K_USER | K_INHERIT_PERMS, K_NO_WAIT);
	k_thread_create(&deadlock2_thread, deadlock2_stack, STACK_SIZE,
			deadlock2_entry, NULL, NULL, NULL,
			K_PRIO_PREEMPT(1), K_USER | K_INHERIT_PERMS, K_NO_WAIT);

	zassert_equal(k_thread_join(&deadlock1_thread, K_FOREVER), 0,
		      "couldn't join deadlock1_thread");
	zassert_equal(k_thread_join(&deadlock2_thread, K_FOREVER), 0,
		      "couldn't join deadlock2_thread");
}

#define WAIT_TO_START_MS 100
/*
 * entry for a delayed thread, do nothing. After the thread is created,
 * just check how many ticks expires and how many ticks remain before
 * the thread start
 */
static void user_start_thread(void *p1, void *p2, void *p3)
{
	/* do nothing */
}

ZTEST_USER(threads_lifecycle, test_thread_timeout_remaining_expires)
{
	k_ticks_t r, e, r1, ticks, expected_expires_ticks;

	ticks = k_ms_to_ticks_ceil32(WAIT_TO_START_MS);
	expected_expires_ticks = k_uptime_ticks() + ticks;

	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
				      user_start_thread, k_current_get(), NULL,
				      NULL, 0, K_USER,
				      K_MSEC(WAIT_TO_START_MS));

	k_msleep(10);
	e = k_thread_timeout_expires_ticks(tid);
	LOG_DBG("thread_expires_ticks: %d, expect: %d", (int)e,
		(int)expected_expires_ticks);
	zassert_true(e >= expected_expires_ticks);

	k_msleep(10);
	r = k_thread_timeout_remaining_ticks(tid);
	zassert_true(r < ticks);
	r1 = r;

	k_msleep(10);
	r = k_thread_timeout_remaining_ticks(tid);
	zassert_true(r < r1);

	k_thread_abort(tid);
}

static void foreach_callback(const struct k_thread *thread, void *user_data)
{

	k_thread_runtime_stats_t stats;
	int ret;

	if (z_is_idle_thread_object((k_tid_t)thread)) {
		return;
	}

	/* Check NULL parameters */
	ret = k_thread_runtime_stats_get(NULL, &stats);
	zassert_true(ret == -EINVAL);
	ret = k_thread_runtime_stats_get((k_tid_t)thread, NULL);
	zassert_true(ret == -EINVAL);

	k_thread_runtime_stats_get((k_tid_t)thread, &stats);
	((k_thread_runtime_stats_t *)user_data)->execution_cycles +=
		stats.execution_cycles;
}

/* This case accumulates every thread's execution_cycles first, then
 * get the total execution_cycles from a global
 * k_thread_runtime_stats_t to see that all time is reflected in the
 * total.
 */
ZTEST(threads_lifecycle, test_thread_runtime_stats_get)
{
	k_thread_runtime_stats_t stats, stats_all;
	int ret;

	stats.execution_cycles = 0;

	k_thread_foreach(foreach_callback, &stats);

	/* Check NULL parameters */
	ret = k_thread_runtime_stats_all_get(NULL);
	zassert_true(ret == -EINVAL);

	k_thread_runtime_stats_all_get(&stats_all);

	zassert_true(stats.execution_cycles <= stats_all.execution_cycles);
}

ZTEST(threads_lifecycle, test_k_busy_wait)
{
	uint64_t cycles, dt;
	k_thread_runtime_stats_t test_stats;

	k_thread_runtime_stats_get(k_current_get(), &test_stats);
	cycles = test_stats.execution_cycles;
	k_busy_wait(0);
	k_thread_runtime_stats_get(k_current_get(), &test_stats);

	/* execution_cycles doesn't increase significantly after 0
	 * usec (10ms slop experimentally determined,
	 * non-deterministic software emulators are VERY slow wrt
	 * their cycle rate)
	 */
	dt = test_stats.execution_cycles - cycles;
	zassert_true(dt < k_ms_to_cyc_ceil64(10));

	cycles = test_stats.execution_cycles;
	k_busy_wait(100);
	k_thread_runtime_stats_get(k_current_get(), &test_stats);

	/* execution_cycles increases correctly */
	dt = test_stats.execution_cycles - cycles;

	/* execution cycles may not increase by the full 100µs as the
	 * system may be doing something else during the busy
	 * wait. Experimentally, we see at least 80% of the cycles
	 * consumed in the busy wait loop on current test targets.
	 */
	zassert_true(dt >= k_us_to_cyc_floor64(80));
}

static void tp_entry(void *p1, void *p2, void *p3)
{
	tp = 100;
}

ZTEST_USER(threads_lifecycle_1cpu, test_k_busy_wait_user)
{

	k_tid_t tid = k_thread_create(&tdata, tstack, STACK_SIZE,
				      tp_entry, NULL, NULL,
				      NULL, 0, K_USER, K_NO_WAIT);
	k_busy_wait(1000);
	/* this is a 1cpu test case, the new thread has no chance to be
	 * scheduled and value of tp not changed
	 */
	zassert_false(tp == 100);

	/* give up cpu, the new thread will change value of tp to 100 */
	k_msleep(100);
	zassert_true(tp == 100);
	k_thread_abort(tid);
}

#define INT_ARRAY_SIZE 128
static int large_stack(size_t *space)
{
	/* use "volatile" to protect this variable from being optimized out */
	volatile int a[INT_ARRAY_SIZE];

	/* to avoid unused variable error */
	a[0] = 1;
	return k_thread_stack_space_get(k_current_get(), space);

}

static int small_stack(size_t *space)
{
	return k_thread_stack_space_get(k_current_get(), space);
}

/* test k_thread_stack_sapce_get(), unused stack space in large_stack_space()
 * is smaller than that in small_stack() because the former function has a
 * large local variable
 */
ZTEST_USER(threads_lifecycle, test_k_thread_stack_space_get_user)
{
	size_t a, b;

	small_stack(&a);
	large_stack(&b);
	/* FIXME: Ideally, the follow condition will assert true:
	 * (a - b) == INT_ARRAY_SIZE * sizeof(int)
	 * but it is not the case in native_posix, qemu_leon3 and
	 * qemu_cortex_a53. Relax check condition here
	 */
	zassert_true(b <= a);
}

static void *thread_test_setup(void)
{
	k_thread_access_grant(k_current_get(), &tdata, tstack,
			      &tdata_custom, tstack_custom,
			      &tdata_name, tstack_name,
			      &join_thread, join_stack,
			      &control_thread, control_stack,
			      &deadlock1_thread, deadlock1_stack,
			      &deadlock2_thread, deadlock2_stack);
	main_prio = k_thread_priority_get(k_current_get());
#ifdef CONFIG_USERSPACE
	strncpy(unreadable_string, "unreadable string",
		sizeof(unreadable_string));
#endif

	return NULL;
}

ZTEST_SUITE(threads_lifecycle, NULL, thread_test_setup, NULL, NULL, NULL);
ZTEST_SUITE(threads_lifecycle_1cpu, NULL, thread_test_setup,
		ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
