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

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

#define N_THR 3
#define STACKSZ (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)

K_THREAD_STACK_ARRAY_DEFINE(stack, N_THR, STACKSZ);
pthread_rwlock_t rwlock;

static void *thread_top(void *p1)
{
	pthread_t pthread;
	uint32_t policy, ret = 0U;
	struct sched_param param;
	int id = POINTER_TO_INT(p1);

	pthread = (pthread_t) pthread_self();
	pthread_getschedparam(pthread, &policy, &param);
	printk("Thread %d scheduling policy = %d & priority %d started\n",
	       id, policy, param.sched_priority);

	ret = pthread_rwlock_tryrdlock(&rwlock);
	if (ret) {
		printk("Not able to get RD lock on trying, try again\n");
		zassert_false(pthread_rwlock_rdlock(&rwlock),
			      "Failed to acquire write lock");
	}

	printk("Thread %d got RD lock\n", id);
	usleep(USEC_PER_MSEC);
	printk("Thread %d releasing RD lock\n", id);
	zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock");

	printk("Thread %d acquiring WR lock\n", id);
	ret = pthread_rwlock_trywrlock(&rwlock);
	if (ret != 0U) {
		zassert_false(pthread_rwlock_wrlock(&rwlock),
			      "Failed to acquire WR lock");
	}

	printk("Thread %d acquired WR lock\n", id);
	usleep(USEC_PER_MSEC);
	printk("Thread %d releasing WR lock\n", id);
	zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock");
	pthread_exit(NULL);
	return NULL;
}

ZTEST(posix_apis, test_posix_rw_lock)
{
	int32_t i, ret;
	pthread_attr_t attr[N_THR];
	struct sched_param schedparam;
	pthread_t newthread[N_THR];
	struct timespec time;
	void *status;

	time.tv_sec = 1;
	time.tv_nsec = 0;

	zassert_equal(pthread_rwlock_destroy(&rwlock), EINVAL);
	zassert_equal(pthread_rwlock_rdlock(&rwlock), EINVAL);
	zassert_equal(pthread_rwlock_wrlock(&rwlock), EINVAL);
	zassert_equal(pthread_rwlock_trywrlock(&rwlock), EINVAL);
	zassert_equal(pthread_rwlock_tryrdlock(&rwlock), EINVAL);
	zassert_equal(pthread_rwlock_timedwrlock(&rwlock, &time), EINVAL);
	zassert_equal(pthread_rwlock_timedrdlock(&rwlock, &time), EINVAL);
	zassert_equal(pthread_rwlock_unlock(&rwlock), EINVAL);

	zassert_false(pthread_rwlock_init(&rwlock, NULL),
		      "Failed to create rwlock");
	printk("\nmain acquire WR lock and 3 threads acquire RD lock\n");
	zassert_false(pthread_rwlock_timedwrlock(&rwlock, &time),
		      "Failed to acquire write lock");

	/* Creating N preemptive threads in increasing order of priority */
	for (i = 0; i < N_THR; i++) {
		zassert_equal(pthread_attr_init(&attr[i]), 0,
			      "Unable to create pthread object attrib");

		/* Setting scheduling priority */
		schedparam.sched_priority = i + 1;
		pthread_attr_setschedparam(&attr[i], &schedparam);

		/* Setting stack */
		pthread_attr_setstack(&attr[i], &stack[i][0], STACKSZ);

		ret = pthread_create(&newthread[i], &attr[i], thread_top,
				     INT_TO_POINTER(i));
		zassert_false(ret, "Low memory to thread new thread");

	}

	/* Delay to give change to child threads to run */
	usleep(USEC_PER_MSEC);
	printk("Parent thread releasing WR lock\n");
	zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock");

	/* Let child threads acquire RD Lock */
	usleep(USEC_PER_MSEC);
	printk("Parent thread acquiring WR lock again\n");

	time.tv_sec = 2;
	time.tv_nsec = 0;
	ret = pthread_rwlock_timedwrlock(&rwlock, &time);

	if (ret) {
		zassert_false(pthread_rwlock_wrlock(&rwlock),
			      "Failed to acquire write lock");
	}

	printk("Parent thread acquired WR lock again\n");
	usleep(USEC_PER_MSEC);
	printk("Parent thread releasing WR lock again\n");
	zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock");

	printk("\n3 threads acquire WR lock\n");
	printk("Main thread acquiring RD lock\n");

	ret = pthread_rwlock_timedrdlock(&rwlock, &time);

	if (ret != 0) {
		zassert_false(pthread_rwlock_rdlock(&rwlock), "Failed to lock");
	}

	printk("Main thread acquired RD lock\n");
	usleep(USEC_PER_MSEC);
	printk("Main thread releasing RD lock\n");
	zassert_false(pthread_rwlock_unlock(&rwlock), "Failed to unlock");

	for (i = 0; i < N_THR; i++) {
		zassert_false(pthread_join(newthread[i], &status),
			      "Failed to join");
	}

	zassert_false(pthread_rwlock_destroy(&rwlock),
		      "Failed to destroy rwlock");
}
