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

#include <ztest.h>
#include <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)
{
	u32_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++) {
		u32_t size = osThreadGetStackSize(thread_array[i]);
		u32_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(z_ms_to_ticks(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 };
	s64_t time_stamp;
	s64_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");
	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(z_ms_to_ticks(DELAY_MS - DELTA_MS));

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

	osDelay(z_ms_to_ticks(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(z_ms_to_ticks(DELAY_MS - DELTA_MS));

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

	osDelay(z_ms_to_ticks(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(z_ms_to_ticks(DELAY_MS - DELTA_MS));

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

	osDelay(z_ms_to_ticks(DELTA_MS));
}
