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

#include <pthread.h>

#include <zephyr/sys/util.h>
#include <zephyr/ztest.h>

#define N_THR 2
#define N_KEY  2
#define BUFFSZ 48

static pthread_key_t key;
static pthread_key_t keys[N_KEY];
static pthread_once_t key_once = PTHREAD_ONCE_INIT;
static pthread_once_t keys_once = PTHREAD_ONCE_INIT;

static void *thread_top(void *p1)
{
	void *value;
	char *buffer[BUFFSZ];

	value = k_malloc(sizeof(buffer));
	zassert_not_null(value, "thread could not allocate storage");
	zassert_ok(pthread_setspecific(key, value), "pthread_setspecific failed");
	zassert_equal(pthread_getspecific(key), value, "set and retrieved values are different");
	k_free(value);

	return NULL;
}

static void *thread_func(void *p1)
{
	void *value;
	char *buffer[BUFFSZ];

	value = k_malloc(sizeof(buffer));
	zassert_not_null(value, "thread could not allocate storage");
	for (int i = 0; i < N_KEY; i++) {
		zassert_ok(pthread_setspecific(keys[i], value), "pthread_setspecific failed");
		zassert_equal(pthread_getspecific(keys[i]), value,
			      "set and retrieved values are different");
	}
	k_free(value);
	return NULL;
}

static void make_key(void)
{
	zassert_ok(pthread_key_create(&key, NULL), "insufficient memory to create key");
}

static void make_keys(void)
{
	for (int i = 0; i < N_KEY; i++) {
		zassert_ok(pthread_key_create(&keys[i], NULL),
			   "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.
 */

ZTEST(key, test_key_1toN_thread)
{
	void *retval;
	pthread_t newthread[N_THR];

	zassert_ok(pthread_once(&key_once, make_key), "attempt to create key failed");

	/* Different threads set different values to same key */

	for (int i = 0; i < N_THR; i++) {
		zassert_ok(pthread_create(&newthread[i], NULL, thread_top, NULL),
			   "attempt to create thread %d failed", i);
	}

	for (int i = 0; i < N_THR; i++) {
		zassert_ok(pthread_join(newthread[i], &retval), "failed to join thread %d", i);
	}

	zassert_ok(pthread_key_delete(key), "attempt to delete key failed");
}

ZTEST(key, test_key_Nto1_thread)
{
	pthread_t newthread;

	zassert_ok(pthread_once(&keys_once, make_keys), "attempt to create keys failed");

	/* Single thread associates its value with different keys */

	zassert_ok(pthread_create(&newthread, NULL, thread_func, NULL),
		   "attempt to create thread failed");

	zassert_ok(pthread_join(newthread, NULL), "failed to join thread");

	for (int i = 0; i < N_KEY; i++) {
		zassert_ok(pthread_key_delete(keys[i]), "attempt to delete keys[%d] failed", i);
	}
}

ZTEST(key, test_key_resource_leak)
{
	pthread_key_t key;

	for (size_t i = 0; i < CONFIG_MAX_PTHREAD_KEY_COUNT; ++i) {
		zassert_ok(pthread_key_create(&key, NULL), "failed to create key %zu", i);
		zassert_ok(pthread_key_delete(key), "failed to delete key %zu", i);
	}
}

ZTEST(key, test_correct_key_is_deleted)
{
	pthread_key_t key;
	size_t j = CONFIG_MAX_PTHREAD_KEY_COUNT - 1;
	pthread_key_t keys[CONFIG_MAX_PTHREAD_KEY_COUNT];

	for (size_t i = 0; i < ARRAY_SIZE(keys); ++i) {
		zassert_ok(pthread_key_create(&keys[i], NULL), "failed to create key %zu", i);
	}

	key = keys[j];
	zassert_ok(pthread_key_delete(keys[j]));
	zassert_ok(pthread_key_create(&keys[j], NULL), "failed to create key %zu", j);

	zassert_equal(key, keys[j], "deleted key %x instead of key %x", keys[j], key);

	for (size_t i = 0; i < ARRAY_SIZE(keys); ++i) {
		zassert_ok(pthread_key_delete(keys[i]), "failed to delete key %zu", i);
	}
}

static void before(void *arg)
{
	ARG_UNUSED(arg);

	if (!IS_ENABLED(CONFIG_DYNAMIC_THREAD)) {
		/* skip redundant testing if there is no thread pool / heap allocation */
		ztest_test_skip();
	}
}

ZTEST_SUITE(key, NULL, NULL, before, NULL, NULL);
