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

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

#define STACKSZ         512

/* 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));
}
