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

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

#define N_THR 2
#define N_KEY 2
#define STACKSZ (1024 + CONFIG_TEST_EXTRA_STACKSIZE)
#define BUFFSZ 48

K_THREAD_STACK_ARRAY_DEFINE(stackp, N_THR, STACKSZ);

pthread_key_t key, keys[N_KEY];
static pthread_once_t key_once, keys_once;

void *thread_top(void *p1)
{
	int ret = -1;

	void *value;
	void *getval;
	char *buffer[BUFFSZ];

	value = k_malloc(sizeof(buffer));

	zassert_true((int)value, "thread could not allocate storage");

	ret = pthread_setspecific(key, (void *)value);

	/* TESTPOINT: Check if thread's value is associated with key */
	zassert_false(ret, "pthread_setspecific failed");

	getval = 0;

	getval = pthread_getspecific(key);

	/* TESTPOINT: Check if pthread_getspecific returns the same value
	 * set by pthread_setspecific
	 */
	zassert_equal(value, getval,
			"set and retrieved values are different");

	printk("set value = %d and retrieved value = %d\n",
			(int)value, (int)getval);

	return NULL;
}

void *thread_func(void *p1)
{
	int i, ret = -1;

	void *value;
	void *getval;
	char *buffer[BUFFSZ];

	value = k_malloc(sizeof(buffer));

	zassert_true((int)value, "thread could not allocate storage");

	for (i = 0; i < N_KEY; i++) {
		ret = pthread_setspecific(keys[i], (void *)value);

		/* TESTPOINT: Check if thread's value is associated with keys */
		zassert_false(ret, "pthread_setspecific failed");
	}

	for (i = 0; i < N_KEY; i++) {
		getval = 0;
		getval = pthread_getspecific(keys[i]);

		/* TESTPOINT: Check if pthread_getspecific returns the same
		 * value set by pthread_setspecific for each of the keys
		 */
		zassert_equal(value, getval,
				"set and retrieved values are different");

		printk("key %d: set value = %d and retrieved value = %d\n",
				i, (int)value, (int)getval);
	}
	return NULL;
}

static void make_key(void)
{
	int ret = 0;

	ret = pthread_key_create(&key, NULL);
	zassert_false(ret, "insufficient memory to create key");
}

static void make_keys(void)
{
	int i, ret = 0;

	for (i = 0; i < N_KEY; i++) {
		ret = pthread_key_create(&keys[i], NULL);
		zassert_false(ret, "insufficient memory to create keys");
	}
}

/**
 * @brief Test to demonstrate pthread_key APIs usage
 *
 * @details The tests spawn a thread which uses pthread_once() to
 * create a key via pthread_key_create() API. It then sets the
 * thread-specific value to the key using pthread_setspecific() and
 * gets it back using pthread_getspecific and asserts that they
 * are equal. It then deletes the key using pthread_key_delete().
 * Both the sub-tests do the above, but one with multiple threads
 * using the same key and the other with a single thread using
 * multiple keys.
 */

void test_posix_multiple_threads_single_key(void)
{
	int i, ret = -1;

	pthread_attr_t attr[N_THR];
	struct sched_param schedparam;
	pthread_t newthread[N_THR];
	void *retval;

	ret = pthread_once(&key_once, make_key);

	/* TESTPOINT: Check if key is created */
	zassert_false(ret, "attempt to create key failed");

	printk("\nDifferent threads set different values to same key:\n");

	/* Creating threads with lowest application priority */
	for (i = 0; i < N_THR; i++) {
		ret = pthread_attr_init(&attr[i]);
		if (ret != 0) {
			zassert_false(pthread_attr_destroy(&attr[i]),
					"Unable to destroy pthread object attr");
			zassert_false(pthread_attr_init(&attr[i]),
					"Unable to create pthread object attr");
		}

		schedparam.sched_priority = 2;
		pthread_attr_setschedparam(&attr[i], &schedparam);
		pthread_attr_setstack(&attr[i], &stackp[i][0], STACKSZ);

		ret = pthread_create(&newthread[i], &attr[i], thread_top,
				(void *)i);

		/* TESTPOINT: Check if threads are created successfully */
		zassert_false(ret, "attempt to create threads failed");
	}

	for (i = 0; i < N_THR; i++) {
		printk("thread %d: ", i);
		pthread_join(newthread[i], &retval);
	}

	ret = pthread_key_delete(key);

	/* TESTPOINT: Check if key is deleted */
	zassert_false(ret, "attempt to delete key failed");
	printk("\n");
}

void test_posix_single_thread_multiple_keys(void)
{
	int i, ret = -1;

	pthread_attr_t attr;
	struct sched_param schedparam;
	pthread_t newthread;

	ret = pthread_once(&keys_once, make_keys);

	/* TESTPOINT: Check if keys are created successfully */
	zassert_false(ret, "attempt to create keys failed");

	printk("\nSingle thread associates its value with different keys:\n");
	ret = pthread_attr_init(&attr);
	if (ret != 0) {
		zassert_false(pthread_attr_destroy(&attr),
				"Unable to destroy pthread object attr");
		zassert_false(pthread_attr_init(&attr),
				"Unable to create pthread object attr");
	}

	schedparam.sched_priority = 2;
	pthread_attr_setschedparam(&attr, &schedparam);
	pthread_attr_setstack(&attr, &stackp[0][0], STACKSZ);

	ret = pthread_create(&newthread, &attr, thread_func,
			(void *)0);

	/*TESTPOINT: Check if thread is created successfully */
	zassert_false(ret, "attempt to create thread failed");

	pthread_join(newthread, NULL);

	for (i = 0; i < N_KEY; i++) {
		ret = pthread_key_delete(keys[i]);

		/* TESTPOINT: Check if keys are deleted */
		zassert_false(ret, "attempt to delete keys failed");
	}
	printk("\n");
}
