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

#include <ztest.h>
#include <zephyr/kernel.h>
#include <cmsis_os2.h>

#define STACKSZ         CONFIG_CMSIS_V2_THREAD_MAX_STACK_SIZE

/* This is used to check the thread yield functionality between 2 threads */
static int thread_yield_check;
static int thread_yield_check_dynamic;

static K_THREAD_STACK_DEFINE(test_stack1, STACKSZ);
static osThreadAttr_t thread1_attr = {
	.name = "Thread1",
	.stack_mem = &test_stack1,
	.stack_size = STACKSZ,
	.priority = osPriorityHigh,
};

static K_THREAD_STACK_DEFINE(test_stack2, STACKSZ);
static osThreadAttr_t thread2_attr = {
	.name = "Thread2",
	.stack_mem = &test_stack2,
	.stack_size = STACKSZ,
	.priority = osPriorityHigh,
};

struct thread1_args {
	int *yield_check;
	const char *name;
};

static void thread1(void *argument)
{
	osStatus_t status;
	osThreadId_t thread_id;
	const char *name;
	struct thread1_args *args = (struct thread1_args *)argument;

	thread_id = osThreadGetId();
	zassert_true(thread_id != NULL, "Failed getting Thread ID");

	name = osThreadGetName(thread_id);
	zassert_true(strcmp(args->name, name) == 0,
		     "Failed getting Thread name");

	/* This thread starts off at a high priority (same as thread2) */
	(*args->yield_check)++;
	zassert_equal(*args->yield_check, 1, NULL);

	/* Yield to thread2 which is of same priority */
	status = osThreadYield();
	zassert_true(status == osOK, "Error doing thread yield");

	/* thread_yield_check should now be 2 as it was incremented
	 * in thread2.
	 */
	zassert_equal(*args->yield_check, 2, NULL);

	osThreadExit();
}

static void thread2(void *argument)
{
	uint32_t i, num_threads, max_num_threads = 5U;
	osThreadId_t *thread_array;
	int *yield_check = (int *)argument;

	/* By now thread1 would have set thread_yield_check to 1 and would
	 * have yielded the CPU. Incrementing it over here would essentially
	 * confirm that the yield was indeed executed.
	 */
	(*yield_check)++;

	thread_array = k_calloc(max_num_threads, sizeof(osThreadId_t));
	num_threads = osThreadEnumerate(thread_array, max_num_threads);
	zassert_equal(num_threads, 2,
		      "Incorrect number of cmsis rtos v2 threads");

	for (i = 0U; i < num_threads; i++) {
		uint32_t size = osThreadGetStackSize(thread_array[i]);
		uint32_t space = osThreadGetStackSpace(thread_array[i]);

		zassert_true(space < size,
			     "stack size remaining is not what is expected");
	}

	zassert_equal(osThreadGetState(thread_array[1]), osThreadReady,
		      "Thread not in ready state");
	zassert_equal(osThreadGetState(thread_array[0]), osThreadRunning,
		      "Thread not in running state");

	zassert_equal(osThreadSuspend(thread_array[1]), osOK, "");
	zassert_equal(osThreadGetState(thread_array[1]), osThreadBlocked,
		      "Thread not in blocked state");

	zassert_equal(osThreadResume(thread_array[1]), osOK, "");
	zassert_equal(osThreadGetState(thread_array[1]), osThreadReady,
		      "Thread not in ready state");

	k_free(thread_array);

	/* Yield back to thread1 which is of same priority */
	osThreadYield();
}

static void thread_apis_common(int *yield_check,
			       const char *thread1_name,
			       osThreadAttr_t *thread1_attr,
			       osThreadAttr_t *thread2_attr)
{
	osThreadId_t id1;
	osThreadId_t id2;

	struct thread1_args args = {
		.yield_check = yield_check,
		.name = thread1_name
	};

	id1 = osThreadNew(thread1, &args, thread1_attr);
	zassert_true(id1 != NULL, "Failed creating thread1");

	id2 = osThreadNew(thread2, yield_check, thread2_attr);
	zassert_true(id2 != NULL, "Failed creating thread2");

	zassert_equal(osThreadGetCount(), 2,
		      "Incorrect number of cmsis rtos v2 threads");

	do {
		osDelay(100);
	} while (*yield_check != 2);
}

void test_thread_apis_dynamic(void)
{
	thread_apis_common(&thread_yield_check_dynamic, "ZephyrThread",
			   NULL, NULL);
}

void test_thread_apis(void)
{
	thread_apis_common(&thread_yield_check, thread1_attr.name,
			   &thread1_attr, &thread2_attr);
}

static osPriority_t OsPriorityInvalid = 60;

/* This is used to indicate the completion of processing for thread3 */
static int thread3_state;
static int thread3_state_dynamic;

static K_THREAD_STACK_DEFINE(test_stack3, STACKSZ);
static osThreadAttr_t thread3_attr = {
	.name = "Thread3",
	.stack_mem = &test_stack3,
	.stack_size = STACKSZ,
	.priority = osPriorityNormal,
};

static void thread3(void *argument)
{
	osStatus_t status;
	osPriority_t rv;
	osThreadId_t id = osThreadGetId();
	osPriority_t prio = osThreadGetPriority(id);
	int *state = (int *)argument;

	/* Lower the priority of the current thread */
	osThreadSetPriority(id, osPriorityBelowNormal);
	rv = osThreadGetPriority(id);
	zassert_equal(rv, osPriorityBelowNormal,
		      "Expected priority to be changed to %d, not %d",
		      (int)osPriorityBelowNormal, (int)rv);

	/* Increase the priority of the current thread */
	osThreadSetPriority(id, osPriorityAboveNormal);
	rv = osThreadGetPriority(id);
	zassert_equal(rv, osPriorityAboveNormal,
		      "Expected priority to be changed to %d, not %d",
		      (int)osPriorityAboveNormal, (int)rv);

	/* Restore the priority of the current thread */
	osThreadSetPriority(id, prio);
	rv = osThreadGetPriority(id);
	zassert_equal(rv, prio,
		      "Expected priority to be changed to %d, not %d",
		      (int)prio, (int)rv);

	/* Try to set unsupported priority and assert failure */
	status = osThreadSetPriority(id, OsPriorityInvalid);
	zassert_true(status == osErrorParameter,
		     "Something's wrong with osThreadSetPriority!");

	/* Indication that thread3 is done with its processing */
	*state = 1;

	/* Keep looping till it gets killed */
	do {
		osDelay(100);
	} while (1);
}

static void thread_prior_common(int *state, osThreadAttr_t *attr)
{
	osStatus_t status;
	osThreadId_t id3;

	id3 = osThreadNew(thread3, state, attr);
	zassert_true(id3 != NULL, "Failed creating thread3");

	/* Keep delaying 10 milliseconds to ensure thread3 is done with
	 * its execution. It loops at the end and is terminated here.
	 */
	do {
		osDelay(10);
	} while (*state == 0);

	status = osThreadTerminate(id3);
	zassert_true(status == osOK, "Error terminating thread3");

	/* Try to set priority to inactive thread and assert failure */
	status = osThreadSetPriority(id3, osPriorityNormal);
	zassert_true(status == osErrorResource,
		     "Something's wrong with osThreadSetPriority!");

	/* Try to terminate inactive thread and assert failure */
	status = osThreadTerminate(id3);
	zassert_true(status == osErrorResource,
		     "Something's wrong with osThreadTerminate!");

	*state = 0;
}

void test_thread_prio_dynamic(void)
{
	thread_prior_common(&thread3_state_dynamic, NULL);
}

void test_thread_prio(void)
{
	thread_prior_common(&thread3_state, &thread3_attr);
}

#define DELAY_MS 1000
#define DELTA_MS 500

static void thread5(void *argument)
{
	printk(" * Thread B started.\n");
	osDelay(k_ms_to_ticks_ceil32(DELAY_MS));
	printk(" * Thread B joining...\n");
}

static void thread4(void *argument)
{
	osThreadId_t tB = argument;
	osStatus_t status;

	printk(" + Thread A started.\n");
	status = osThreadJoin(tB);
	zassert_equal(status, osOK, "osThreadJoin thread B failed!");
	printk(" + Thread A joining...\n");
}

void test_thread_join(void)
{
	osThreadAttr_t attr = { 0 };
	int64_t time_stamp;
	int64_t milliseconds_spent;
	osThreadId_t tA, tB;
	osStatus_t status;

	attr.attr_bits = osThreadJoinable;

	time_stamp = k_uptime_get();

	printk(" - Creating thread B...\n");
	tB = osThreadNew(thread5, NULL, &attr);
	zassert_not_null(tB, "Failed to create thread B with osThreadNew!");

	printk(" - Creating thread A...\n");
	attr.priority = osPriorityLow;
	tA = osThreadNew(thread4, tB, &attr);
	zassert_not_null(tA, "Failed to create thread A with osThreadNew!");

	printk(" - Waiting for thread B to join...\n");
	status = osThreadJoin(tB);
	zassert_equal(status, osOK, "osThreadJoin thread B failed!");

	if (status == osOK) {
		printk(" - Thread B joined.\n");
	}

	milliseconds_spent = k_uptime_delta(&time_stamp);
	zassert_true((milliseconds_spent >= DELAY_MS - DELTA_MS) &&
		     (milliseconds_spent <= DELAY_MS + DELTA_MS),
		     "Join completed but was too fast or too slow.");

	printk(" - Waiting for thread A to join...\n");
	status = osThreadJoin(tA);
	zassert_equal(status, osOK, "osThreadJoin thread A failed!");

	if (status == osOK) {
		printk(" - Thread A joined.\n");
	}
}

void test_thread_detached(void)
{
	osThreadId_t thread;
	osStatus_t status;

	thread = osThreadNew(thread5, NULL, NULL); /* osThreadDetached */
	zassert_not_null(thread, "Failed to create thread with osThreadNew!");

	osDelay(k_ms_to_ticks_ceil32(DELAY_MS - DELTA_MS));

	status = osThreadJoin(thread);
	zassert_equal(status, osErrorResource,
		      "Incorrect status returned from osThreadJoin!");

	osDelay(k_ms_to_ticks_ceil32(DELTA_MS));
}

void thread6(void *argument)
{
	osThreadId_t thread = argument;
	osStatus_t status;

	status = osThreadJoin(thread);
	zassert_equal(status, osErrorResource,
		      "Incorrect status returned from osThreadJoin!");
}

void test_thread_joinable_detach(void)
{
	osThreadAttr_t attr = { 0 };
	osThreadId_t tA, tB;
	osStatus_t status;

	attr.attr_bits = osThreadJoinable;

	tA = osThreadNew(thread5, NULL, &attr);
	zassert_not_null(tA, "Failed to create thread with osThreadNew!");

	tB = osThreadNew(thread6, tA, &attr);
	zassert_not_null(tB, "Failed to create thread with osThreadNew!");

	osDelay(k_ms_to_ticks_ceil32(DELAY_MS - DELTA_MS));

	status = osThreadDetach(tA);
	zassert_equal(status, osOK, "osThreadDetach failed.");

	osDelay(k_ms_to_ticks_ceil32(DELTA_MS));
}

void test_thread_joinable_terminate(void)
{
	osThreadAttr_t attr = { 0 };
	osThreadId_t tA, tB;
	osStatus_t status;

	attr.attr_bits = osThreadJoinable;

	tA = osThreadNew(thread5, NULL, &attr);
	zassert_not_null(tA, "Failed to create thread with osThreadNew!");

	tB = osThreadNew(thread6, tA, &attr);
	zassert_not_null(tB, "Failed to create thread with osThreadNew!");

	osDelay(k_ms_to_ticks_ceil32(DELAY_MS - DELTA_MS));

	status = osThreadTerminate(tA);
	zassert_equal(status, osOK, "osThreadTerminate failed.");

	osDelay(k_ms_to_ticks_ceil32(DELTA_MS));
}
