/*
 * Copyright (c) 2023, Meta
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "thrd.h"

#include <stdint.h>
#include <threads.h>

#include <zephyr/ztest.h>

#define WAIT_TIME_MS 100

static struct libc_cnd_fixture {
	/* shared between threads in tests */
	cnd_t cond;
	mtx_t mutex;

	/* de-duplicate local variables in test cases */
	int res1;
	int res2;
	thrd_t thrd1;
	thrd_t thrd2;
	bool do_timedwait;
	bool is_broadcast;
	struct timespec time_point;
} _libc_cnd_fixture;

ZTEST_F(libc_cnd, test_cnd_init_destroy)
{
	/* degenerate cases */
	if (false) {
		/* pthread_cond_init() pthread_cond_destroy() are not hardened against these */
		zassert_equal(thrd_error, cnd_init(NULL));
		zassert_equal(thrd_error, cnd_init((cnd_t *)BIOS_FOOD));
		cnd_destroy(NULL);
		cnd_destroy((cnd_t *)BIOS_FOOD);
	}

	/* happy path tested in before() / after() */
}

ZTEST_F(libc_cnd, test_cnd_errors)
{
	/* degenerate test cases */
	if (false) {
		/* pthread_cond_*() are not hardened against these */
		zassert_equal(thrd_error, cnd_signal(NULL));
		zassert_equal(thrd_error, cnd_broadcast(NULL));
		zassert_equal(thrd_error, cnd_wait(NULL, NULL));
		zassert_equal(thrd_error, cnd_wait(NULL, &fixture->mutex));
		zassert_equal(thrd_error, cnd_wait(&fixture->cond, NULL));
		zassert_equal(thrd_error, cnd_timedwait(NULL, NULL, NULL));
		zassert_equal(thrd_error, cnd_timedwait(NULL, NULL, &fixture->time_point));
		zassert_equal(thrd_error, cnd_timedwait(NULL, &fixture->mutex, NULL));
		zassert_equal(thrd_error,
			      cnd_timedwait(NULL, &fixture->mutex, &fixture->time_point));
		zassert_equal(thrd_error, cnd_timedwait(&fixture->cond, NULL, NULL));
		zassert_equal(thrd_error,
			      cnd_timedwait(&fixture->cond, NULL, &fixture->time_point));
		zassert_equal(thrd_error, cnd_timedwait(&fixture->cond, &fixture->mutex, NULL));
	}
}

static int test_cnd_thread_fn(void *arg)
{
	int res = thrd_success;
	struct timespec time_point;
	struct libc_cnd_fixture *const fixture = arg;

	if (fixture->do_timedwait) {
		zassume_ok(clock_gettime(CLOCK_MONOTONIC, &time_point));
		timespec_add_ms(&time_point, WAIT_TIME_MS);
		res = cnd_timedwait(&fixture->cond, &fixture->mutex, &time_point);
	} else {
		res = cnd_wait(&fixture->cond, &fixture->mutex);
	}

	if (fixture->is_broadcast) {
		/* re-signal so that the next thread wakes up too */
		zassert_equal(thrd_success, cnd_signal(&fixture->cond));
	}

	(void)mtx_unlock(&fixture->mutex);

	return res;
}

static void tst_cnd_common(struct libc_cnd_fixture *fixture, size_t wait_ms, bool th2, int exp1,
			   int exp2)
{
	zassert_equal(thrd_success, mtx_lock(&fixture->mutex));

	zassert_equal(thrd_success, thrd_create(&fixture->thrd1, test_cnd_thread_fn, fixture));
	if (th2) {
		zassert_equal(thrd_success,
			      thrd_create(&fixture->thrd2, test_cnd_thread_fn, fixture));
	}

	k_msleep(wait_ms);

	if (fixture->is_broadcast) {
		zassert_equal(thrd_success, cnd_broadcast(&fixture->cond));
	} else {
		zassert_equal(thrd_success, cnd_signal(&fixture->cond));
	}

	zassert_equal(thrd_success, mtx_unlock(&fixture->mutex));

	zassert_equal(thrd_success, thrd_join(fixture->thrd1, &fixture->res1));
	if (th2) {
		zassert_equal(thrd_success, thrd_join(fixture->thrd2, &fixture->res2));
	}

	zassert_equal(exp1, fixture->res1);
	if (th2) {
		zassert_equal(exp2, fixture->res2);
	}
}

ZTEST_F(libc_cnd, test_cnd_signal_wait)
{
	tst_cnd_common(fixture, WAIT_TIME_MS / 2, false, thrd_success, DONT_CARE);
}

ZTEST_F(libc_cnd, test_cnd_signal_timedwait)
{
	fixture->do_timedwait = true;
	tst_cnd_common(fixture, WAIT_TIME_MS / 2, false, thrd_success, DONT_CARE);
}

ZTEST_F(libc_cnd, test_cnd_timedwait_timeout)
{
	fixture->do_timedwait = true;
	tst_cnd_common(fixture, WAIT_TIME_MS * 2, false, thrd_timedout, DONT_CARE);
}

ZTEST_F(libc_cnd, test_cnd_broadcast_wait)
{
	fixture->is_broadcast = true;
	tst_cnd_common(fixture, WAIT_TIME_MS, true, thrd_success, thrd_success);
}

static void *setup(void)
{
	return &_libc_cnd_fixture;
}

static void before(void *arg)
{
	struct libc_cnd_fixture *const fixture = arg;

	*fixture = (struct libc_cnd_fixture){
		.res1 = FORTY_TWO,
		.res2 = SEVENTY_THREE,
	};

	zassert_equal(thrd_success, mtx_init(&fixture->mutex, mtx_plain));
	zassert_equal(thrd_success, cnd_init(&fixture->cond));
}

static void after(void *arg)
{
	struct libc_cnd_fixture *const fixture = arg;

	cnd_destroy(&fixture->cond);
	mtx_destroy(&fixture->mutex);
}

ZTEST_SUITE(libc_cnd, NULL, setup, before, after, NULL);
