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

#include <ztest.h>
#include <zephyr.h>
#include <errno.h>

/**
 * @brief Test the thread context
 *
 * @defgroup kernel_threadcontext_tests Thread Context Tests
 *
 * @ingroup all_tests
 *
 * @{
 * @}
 */
#define N_THREADS 2
#define STACK_SIZE (384 + CONFIG_TEST_EXTRA_STACKSIZE)

static K_THREAD_STACK_ARRAY_DEFINE(stacks, N_THREADS, STACK_SIZE);
static struct k_thread threads[N_THREADS];

K_THREAD_STACK_DEFINE(eno_stack, STACK_SIZE);
struct k_thread eno_thread;

static int errno_values[N_THREADS + 1] = {
	0xbabef00d,
	0xdeadbeef,
	0xabad1dea,
};

struct result {
	void *q;
	int pass;
};

struct result result[N_THREADS];

struct k_fifo fifo;

static void errno_thread(void *_n, void *_my_errno, void *_unused)
{
	int n = POINTER_TO_INT(_n);
	int my_errno = POINTER_TO_INT(_my_errno);

	errno = my_errno;

	k_msleep(30 - (n * 10));
	if (errno == my_errno) {
		result[n].pass = 1;
	}

	zassert_equal(errno, my_errno, NULL);

	k_fifo_put(&fifo, &result[n]);
}

/**
 * @brief Verify thread context
 *
 * @ingroup kernel_threadcontext_tests
 *
 * @details Check whether variable value per-thread are saved during
 *	context switch
 */
void test_thread_context(void)
{
	int rv = TC_PASS, test_errno;

	k_fifo_init(&fifo);

	errno = errno_values[N_THREADS];
	test_errno = errno;

	for (int ii = 0; ii < N_THREADS; ii++) {
		result[ii].pass = TC_FAIL;
	}

	/**TESTPOINT: thread- threads stacks are separate */
	for (int ii = 0; ii < N_THREADS; ii++) {
		k_thread_create(&threads[ii], stacks[ii], STACK_SIZE,
				errno_thread, INT_TO_POINTER(ii),
				INT_TO_POINTER(errno_values[ii]), NULL,
				K_PRIO_PREEMPT(ii + 5), 0, K_NO_WAIT);
	}

	for (int ii = 0; ii < N_THREADS; ii++) {
		struct result *p = k_fifo_get(&fifo, K_MSEC(100));

		if (!p || !p->pass) {
			rv = TC_FAIL;
		}
	}

	zassert_equal(errno, test_errno, NULL);

	if (errno != errno_values[N_THREADS]) {
		rv = TC_FAIL;
	}

	/* Make sure all the test thread end. */
	for (int ii = 0; ii < N_THREADS; ii++) {
		k_thread_join(&threads[ii], K_FOREVER);
	}
}


#define ERROR_ANY 0xfc

void thread_entry_user(void *p1, void *p2, void *p3)
{
#ifdef CONFIG_ARCH_POSIX
	/* The errno in native posix will be handled by native
	 * operation system, so we skip it.
	 */
	ztest_test_skip();
#else
	int got_errno;

	/* assign the error number to C standard errno */
	errno = ERROR_ANY;

	/* got errno zephyr stored */
	got_errno = *(z_errno());

	zassert_equal(errno, got_errno, "errno is not corresponding.");
#endif
}

/**
 * @brief Verify errno works well
 *
 * @details Check whether a C standard errno can be stored successfully,
 *  no matter it is using tls or not.
 *
 * @ingroup kernel_threadcontext_tests
 */
void test_errno(void)
{
	k_tid_t tid;
	uint32_t perm = K_INHERIT_PERMS;

	if (k_is_user_context()) {
		perm = perm | K_USER;
	}

	tid = k_thread_create(&eno_thread, eno_stack, STACK_SIZE,
				thread_entry_user, NULL, NULL, NULL,
				K_PRIO_PREEMPT(1), perm,
				K_NO_WAIT);

	k_thread_join(tid, K_FOREVER);
}
