/*****************************************************************************\
 *  Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
\*****************************************************************************/

#include <check.h>

#include "src/common/log.h"
#include "src/common/macros.h"
#include "src/common/read_config.h"
#include "src/common/slurm_protocol_defs.h"

#include "src/common/workerpool.h"

#if SLURM_VERSION_NUMBER >= SLURM_VERSION_NUM(26, 11, 0)

#define THREAD_COUNT 4
#define WORK_COUNT 8

static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

/* Total callbacks that have completed */
static int done = 0;
/* Callbacks currently executing */
static int active = 0;
/* Highest number of callbacks seen running at once */
static int peak = 0;
/* Hold blocking callbacks until the test releases them */
static bool release = false;

static void _reset(void)
{
	slurm_mutex_lock(&lock);
	done = 0;
	active = 0;
	peak = 0;
	release = false;
	slurm_mutex_unlock(&lock);
}

/* Increment the completion counter and signal the test thread */
static void _count_work(const bool shutdown, void *arg)
{
	slurm_mutex_lock(&lock);
	done++;
	slurm_cond_broadcast(&cond);
	slurm_mutex_unlock(&lock);
}

/*
 * Track concurrency: bump active/peak on entry, then block until the test
 * thread sets release so several callbacks overlap in flight.
 */
static void _blocking_work(const bool shutdown, void *arg)
{
	slurm_mutex_lock(&lock);
	active++;
	if (active > peak)
		peak = active;
	slurm_cond_broadcast(&cond);

	while (!release)
		slurm_cond_wait(&cond, &lock);

	active--;
	done++;
	slurm_cond_broadcast(&cond);
	slurm_mutex_unlock(&lock);
}

static void setup(void)
{
	log_options_t log_opts = LOG_OPTS_INITIALIZER;
	const char *debug_env = getenv("SLURM_DEBUG");
	const char *debug_flags_env = getenv("SLURM_DEBUG_FLAGS");

	/* Setup logging */
	if (debug_env)
		log_opts.stderr_level = log_string2num(debug_env);
	if (debug_flags_env)
		debug_str2flags(debug_flags_env, &slurm_conf.debug_flags);
	log_init("workerpool-test", log_opts, 0, NULL);
}

static void teardown(void)
{
	log_fini();
}

START_TEST(test_init_fini)
{
	workerpool_init(0, THREAD_COUNT, NULL);
	/* Re-init while running is a no-op */
	workerpool_init(0, THREAD_COUNT, NULL);

	workerpool_fini();
	/* Double fini must be safe */
	workerpool_fini();
}

END_TEST

START_TEST(test_enqueue)
{
	_reset();

	workerpool_init(0, THREAD_COUNT, NULL);

	for (int i = 0; i < WORK_COUNT; i++)
		workerpool_enqueue_normal(_count_work, NULL);

	/* Wait for every callback to complete */
	slurm_mutex_lock(&lock);
	while (done < WORK_COUNT)
		slurm_cond_wait(&cond, &lock);
	slurm_mutex_unlock(&lock);

	ck_assert_int_eq(done, WORK_COUNT);

	workerpool_fini();
}

END_TEST

START_TEST(test_concurrency)
{
	_reset();

	/* Configure an explicit, known thread count */
	workerpool_init(0, 0, "workerpool_threads=" XSTRINGIFY(THREAD_COUNT));

	for (int i = 0; i < WORK_COUNT; i++)
		workerpool_enqueue_normal(_blocking_work, NULL);

	/* Wait until at least two callbacks overlap, proving real concurrency */
	slurm_mutex_lock(&lock);
	while (active < 2)
		slurm_cond_wait(&cond, &lock);
	/* Release every blocked callback */
	release = true;
	slurm_cond_broadcast(&cond);
	while (done < WORK_COUNT)
		slurm_cond_wait(&cond, &lock);
	slurm_mutex_unlock(&lock);

	ck_assert_int_eq(done, WORK_COUNT);
	/* Concurrency happened but never exceeded the configured thread count */
	ck_assert_int_ge(peak, 2);
	ck_assert_int_le(peak, THREAD_COUNT);

	workerpool_fini();
}

END_TEST

START_TEST(test_conmgr_threads_alias)
{
	_reset();

	/* conmgr_threads= must be accepted as an alias for workerpool_threads= */
	workerpool_init(0, 0, "conmgr_threads=" XSTRINGIFY(THREAD_COUNT));

	for (int i = 0; i < WORK_COUNT; i++)
		workerpool_enqueue_normal(_count_work, NULL);

	slurm_mutex_lock(&lock);
	while (done < WORK_COUNT)
		slurm_cond_wait(&cond, &lock);
	slurm_mutex_unlock(&lock);

	ck_assert_int_eq(done, WORK_COUNT);

	workerpool_fini();
}

END_TEST

#endif /* SLURM_VERSION_NUMBER >= SLURM_VERSION_NUM(26,11,0) */

extern int main(int argc, char **argv)
{
	int failures;

	TCase *tcase = tcase_create("workerpool");
#if SLURM_VERSION_NUMBER >= SLURM_VERSION_NUM(26, 11, 0)
	tcase_add_unchecked_fixture(tcase, setup, teardown);
	/* Concurrency test blocks worker threads; allow generous wall time */
	tcase_set_timeout(tcase, 60);
	tcase_add_test(tcase, test_init_fini);
	tcase_add_test(tcase, test_enqueue);
	tcase_add_test(tcase, test_concurrency);
	tcase_add_test(tcase, test_conmgr_threads_alias);
#endif

	Suite *suite = suite_create("workerpool");
	suite_add_tcase(suite, tcase);

	SRunner *sr = srunner_create(suite);
	srunner_run_all(sr, CK_VERBOSE);
	failures = srunner_ntests_failed(sr);
	srunner_free(sr);

	return failures;
}
