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

#include <errno.h>
#include <pthread.h>

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

#define SLEEP_MS 100

static pthread_mutex_t mutex;

static void *normal_mutex_entry(void *p1)
{
	int i, rc;

	/* Sleep for maximum 300 ms as main thread is sleeping for 100 ms */

	for (i = 0; i < 3; i++) {
		rc = pthread_mutex_trylock(&mutex);
		if (rc == 0) {
			break;
		}
		k_msleep(SLEEP_MS);
	}

	zassert_false(rc, "try lock failed");
	TC_PRINT("mutex lock is taken\n");
	zassert_false(pthread_mutex_unlock(&mutex), "mutex unlock is failed");
	return NULL;
}

static void *recursive_mutex_entry(void *p1)
{
	zassert_false(pthread_mutex_lock(&mutex), "mutex is not taken");
	zassert_false(pthread_mutex_lock(&mutex), "mutex is not taken 2nd time");
	TC_PRINT("recursive mutex lock is taken\n");
	zassert_false(pthread_mutex_unlock(&mutex), "mutex is not unlocked");
	zassert_false(pthread_mutex_unlock(&mutex), "mutex is not unlocked");
	return NULL;
}

static void test_mutex_common(int type, void *(*entry)(void *arg))
{
	pthread_t th;
	int protocol;
	int actual_type;
	struct sched_param schedparam;
	pthread_mutexattr_t mut_attr = {0};

	schedparam.sched_priority = 2;

	zassert_ok(pthread_mutexattr_settype(&mut_attr, type), "setting mutex type is failed");
	zassert_ok(pthread_mutex_init(&mutex, &mut_attr), "mutex initialization is failed");

	zassert_ok(pthread_mutexattr_gettype(&mut_attr, &actual_type),
		   "reading mutex type is failed");
	zassert_ok(pthread_mutexattr_getprotocol(&mut_attr, &protocol),
		   "reading mutex protocol is failed");

	zassert_ok(pthread_mutex_lock(&mutex));

	zassert_equal(actual_type, type, "mutex type is not normal");
	zassert_equal(protocol, PTHREAD_PRIO_NONE, "mutex protocol is not prio_none");

	zassert_ok(pthread_create(&th, NULL, entry, NULL));

	k_msleep(SLEEP_MS);
	zassert_ok(pthread_mutex_unlock(&mutex));

	zassert_ok(pthread_join(th, NULL));
	zassert_ok(pthread_mutex_destroy(&mutex), "Destroying mutex is failed");
}

/**
 * @brief Test to demonstrate PTHREAD_MUTEX_NORMAL
 *
 * @details Mutex type is setup as normal. pthread_mutex_trylock
 *	    and pthread_mutex_lock are tested with mutex type being
 *	    normal.
 */
ZTEST(mutex, test_mutex_normal)
{
	test_mutex_common(PTHREAD_MUTEX_NORMAL, normal_mutex_entry);
}

/**
 * @brief Test to demonstrate PTHREAD_MUTEX_RECURSIVE
 *
 * @details Mutex type is setup as recursive. mutex will be locked
 *	    twice and unlocked for the same number of time.
 *
 */
ZTEST(mutex, test_mutex_recursive)
{
	test_mutex_common(PTHREAD_MUTEX_RECURSIVE, recursive_mutex_entry);
}

/**
 * @brief Test to demonstrate limited mutex resources
 *
 * @details Exactly CONFIG_MAX_PTHREAD_MUTEX_COUNT can be in use at once.
 */
ZTEST(mutex, test_mutex_resource_exhausted)
{
	size_t i;
	pthread_mutex_t m[CONFIG_MAX_PTHREAD_MUTEX_COUNT + 1];

	for (i = 0; i < CONFIG_MAX_PTHREAD_MUTEX_COUNT; ++i) {
		zassert_ok(pthread_mutex_init(&m[i], NULL), "failed to init mutex %zu", i);
	}

	/* try to initialize one more than CONFIG_MAX_PTHREAD_MUTEX_COUNT */
	zassert_equal(i, CONFIG_MAX_PTHREAD_MUTEX_COUNT);
	zassert_not_equal(0, pthread_mutex_init(&m[i], NULL),
			  "should not have initialized mutex %zu", i);

	for (; i > 0; --i) {
		zassert_ok(pthread_mutex_destroy(&m[i - 1]), "failed to destroy mutex %zu", i - 1);
	}
}

/**
 * @brief Test to that there are no mutex resource leaks
 *
 * @details Demonstrate that mutexes may be used over and over again.
 */
ZTEST(mutex, test_mutex_resource_leak)
{
	pthread_mutex_t m;

	for (size_t i = 0; i < 2 * CONFIG_MAX_PTHREAD_MUTEX_COUNT; ++i) {
		zassert_ok(pthread_mutex_init(&m, NULL), "failed to init mutex %zu", i);
		zassert_ok(pthread_mutex_destroy(&m), "failed to destroy mutex %zu", i);
	}
}

#define TIMEDLOCK_TIMEOUT_MS       200
#define TIMEDLOCK_TIMEOUT_DELAY_MS 100

BUILD_ASSERT(TIMEDLOCK_TIMEOUT_DELAY_MS >= 100, "TIMEDLOCK_TIMEOUT_DELAY_MS too small");
BUILD_ASSERT(TIMEDLOCK_TIMEOUT_MS >= 2 * TIMEDLOCK_TIMEOUT_DELAY_MS,
	     "TIMEDLOCK_TIMEOUT_MS too small");

static void timespec_add_ms(struct timespec *ts, uint32_t ms)
{
	bool oflow;

	ts->tv_nsec += ms * NSEC_PER_MSEC;
	oflow = ts->tv_nsec >= NSEC_PER_SEC;
	ts->tv_sec += oflow;
	ts->tv_nsec -= oflow * NSEC_PER_SEC;
}

static void *test_mutex_timedlock_fn(void *arg)
{
	struct timespec time_point;
	pthread_mutex_t *mtx = (pthread_mutex_t *)arg;

	zassume_ok(clock_gettime(CLOCK_MONOTONIC, &time_point));
	timespec_add_ms(&time_point, TIMEDLOCK_TIMEOUT_MS);

	return INT_TO_POINTER(pthread_mutex_timedlock(mtx, &time_point));
}

/** @brief Test to verify @ref pthread_mutex_timedlock returns ETIMEDOUT */
ZTEST(mutex, test_mutex_timedlock)
{
	void *ret;
	pthread_t th;

	zassert_ok(pthread_mutex_init(&mutex, NULL));

	printk("Expecting timedlock with timeout of %d ms to fail\n", TIMEDLOCK_TIMEOUT_MS);
	zassert_ok(pthread_mutex_lock(&mutex));
	zassert_ok(pthread_create(&th, NULL, test_mutex_timedlock_fn, &mutex));
	zassert_ok(pthread_join(th, &ret));
	/* ensure timeout occurs */
	zassert_equal(ETIMEDOUT, POINTER_TO_INT(ret));

	printk("Expecting timedlock with timeout of %d ms to succeed after 100ms\n",
	       TIMEDLOCK_TIMEOUT_MS);
	zassert_ok(pthread_create(&th, NULL, test_mutex_timedlock_fn, &mutex));
	/* unlock before timeout expires */
	k_msleep(TIMEDLOCK_TIMEOUT_DELAY_MS);
	zassert_ok(pthread_mutex_unlock(&mutex));
	zassert_ok(pthread_join(th, &ret));
	/* ensure lock is successful, in spite of delay  */
	zassert_ok(POINTER_TO_INT(ret));

	zassert_ok(pthread_mutex_destroy(&mutex));
}

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(mutex, NULL, NULL, before, NULL, NULL);
