// SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause
/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
#include <test_progs.h>
#include <unistd.h>

#include <libarena/common.h>
#include <libarena/asan.h>
#include <libarena/buddy.h>
#include <libarena/userspace.h>

#include "libarena/libarena.skel.h"

static void run_libarena_test(struct libarena *skel, struct bpf_program *prog,
		const char *name)
{
	int ret;

	if (strstr(name, "test_buddy")) {
		/* Buddy tests initialize the allocator directly. */
		ret = libarena_run_prog(bpf_program__fd(skel->progs.arena_buddy_destroy));
		if (!ASSERT_OK(ret, "arena_buddy_destroy"))
			return;
	} else {
		ret = libarena_run_prog(bpf_program__fd(skel->progs.arena_buddy_reset));
		if (!ASSERT_OK(ret, "arena_buddy_reset"))
			return;
	}

	ret = libarena_run_prog(bpf_program__fd(prog));

	ASSERT_OK(ret, name);
}

static void *run_libarena_parallel_prog(void *arg)
{
	struct bpf_program *prog = arg;

	return (void *)(long)libarena_run_prog(bpf_program__fd(prog));
}

/* Max suffix is ceil((lg 2^32) / (lg 10)) + sizeof("__") = 10 + 2 = 12. */
#define MAX_PARTEST_SUFFIX (12)
#define MAX_PARTEST_NAME (1024)
#define MAX_PARTEST_PREFIX (MAX_PARTEST_NAME - MAX_PARTEST_SUFFIX)

static int run_libarena_parallel_fini(struct libarena *skel, const char *name,
				      size_t prefixlen)
{
	char tdname[MAX_PARTEST_NAME];
	struct bpf_program *fini_prog;
	int ret;

	ret = snprintf(tdname, sizeof(tdname), "%.*s__fini", (int)prefixlen, name);
	if (!ASSERT_LT(ret, sizeof(tdname), "partest fini name"))
		return -ENAMETOOLONG;

	fini_prog = bpf_object__find_program_by_name(skel->obj, tdname);
	if (!ASSERT_TRUE(fini_prog, "partest fini prog"))
		return -ENOENT;

	ret = libarena_run_prog(bpf_program__fd(fini_prog));
	ASSERT_OK(ret, tdname);

	return ret;
}

static int run_libarena_parallel_test_workers(struct libarena *skel,
		const char *name, size_t prefixlen)
{
	pthread_t *threads = NULL, *tmp_threads;
	char tdname[MAX_PARTEST_NAME];
	struct bpf_program *tdprog;
	uint32_t nthreads;
	void *thread_ret;
	int ret, err = 0;
	int worker_err;
	int i;

	for (nthreads = 0; nthreads < UINT_MAX; nthreads++) {
		ret = snprintf(tdname, sizeof(tdname), "%.*s__%u", (int)prefixlen,
			       name, nthreads);
		if (!ASSERT_LT(ret, sizeof(tdname), "test worker name")) {
			err = -ENAMETOOLONG;
			break;
		}

		/* 
		 * We enumerate the worker threads for a given test with __0, __1,
		 * and so on. The suffixes always start from 0 and are contiguous,
		 * so if we don't find a program with the requested name we have
		 * discovered all available worker programs.
		 */
		tdprog = bpf_object__find_program_by_name(skel->obj, tdname);
		if (!tdprog)
			break;

		/* Bump the alloc array to accommodate the new thread. */
		tmp_threads = realloc(threads, (nthreads + 1) * sizeof(*threads));
		if (!ASSERT_TRUE(tmp_threads, "realloc")) {
			err = -ENOMEM;
			break;
		}
		threads = tmp_threads;

		ret = pthread_create(&threads[nthreads], NULL,
				     run_libarena_parallel_prog,
				     tdprog);
		if (!ASSERT_OK(ret, "pthread_create")) {
			err = ret;
			break;
		}
	}


	for (i = 0; i < nthreads; i++) {
		ret = pthread_join(threads[i], &thread_ret);
		if (!ASSERT_OK(ret, "pthread_join")) {
			err = err ?: ret;
			continue;
		}

		worker_err = (long)thread_ret;

		/*
		 * A worker that bails out because another one already gave up
		 * reports -EINTR. It is collateral damage that carries no
		 * information, so skip it entirely: never let it become the
		 * reported error, and don't log it either.
		 */
		if (!worker_err || worker_err == -EINTR)
			continue;

		if (!err)
			err = worker_err;

		fprintf(stdout, "%.*s__%d returned %d\n", (int)prefixlen, name,
			i, worker_err);
	}

	free(threads);

	return err;
}

static bool libarena_parallel_test_enabled(struct libarena *skel,
					   const char *prefix,
					   size_t prefixlen)
{
	struct bpf_program *prog;
	char progname[MAX_PARTEST_NAME];
	int ret;

	ret = snprintf(progname, sizeof(progname), "%.*s__enabled", (int)prefixlen,
		       prefix);
	if (!ASSERT_LT(ret, sizeof(progname), "partest enabled name"))
		return false;

	prog = bpf_object__find_program_by_name(skel->obj, progname);
	if (!prog)
		return true;

	ret = libarena_run_prog(bpf_program__fd(prog));
	if (ret == -EOPNOTSUPP)
		return false;
	if (!ASSERT_OK(ret, progname))
		return false;
	return true;
}

static void run_libarena_parallel_test(struct libarena *skel, struct bpf_program *prog,
		const char *name)
{
	char testname[MAX_PARTEST_NAME];
	size_t prefixlen;
	const char *pos;
	int ret;

	/*
	 * We annotate the initialization prog with __init. If the current prog does
	 * not match, it is one of the parallel threads instead and is ignored.
	 *
	 * We assume the test writer knows what they are doing and do not add __init
	 * randomly in the middle of a test name.
	 */
	pos = strstr(name, "__init");
	if (!pos)
		return;

	prefixlen = pos - name;
	if (!ASSERT_LT(prefixlen, MAX_PARTEST_PREFIX, "partest prefix too long"))
		return;

	/* The name of the test without the __init suffix. Looks nicer in the test log. */
	ret = snprintf(testname, sizeof(testname), "%.*s", (int)prefixlen, name);
	if (!ASSERT_LT(ret, sizeof(testname), "partest test name"))
		return;

	if (!test__start_subtest(testname))
		return;

	if (!libarena_parallel_test_enabled(skel, testname, prefixlen)) {
		test__skip();
		return;
	}

	ret = libarena_run_prog(bpf_program__fd(skel->progs.arena_buddy_reset));
	if (!ASSERT_OK(ret, "arena_buddy_reset"))
		return;

	ret = libarena_run_prog(bpf_program__fd(prog));
	if (!ASSERT_OK(ret, testname))
		return;

	ret = run_libarena_parallel_test_workers(skel, name, prefixlen);

	ASSERT_OK(ret, testname);

	run_libarena_parallel_fini(skel, name, prefixlen);
}

void serial_test_libarena(void)
{
	struct arena_alloc_reserve_args args;
	struct libarena *skel;
	struct bpf_program *prog;
	int ret;

	skel = libarena__open_and_load();
	if (!ASSERT_OK_PTR(skel, "open_and_load"))
		return;

	ret = libarena__attach(skel);
	if (!ASSERT_OK(ret, "attach"))
		goto out;

	args.nr_pages = ARENA_RESERVE_PAGES_DFL;

	ret = libarena_run_prog_args(bpf_program__fd(skel->progs.arena_alloc_reserve),
			&args, sizeof(args));
	if (!ASSERT_OK(ret, "arena_alloc_reserve"))
		goto out;

	bpf_object__for_each_program(prog, skel->obj) {
		const char *name = bpf_program__name(prog);

		/*
		 * Handle parallel test progs separately. For those
		 * progs it's not a matter of test/skip, because each
		 * parallel test prog includes an initialization prog
		 * and a set of progs to be run in parallel. For the
		 * latter we do not record them as skipped or run,
		 * because we run them all at once when we come across
		 * the initialization prog. For more details on how we
		 * discover the progs see the comment on
		 * run_libarena_parallel_test.
		 */
		if (libarena_is_parallel_test_prog(name)) {
			run_libarena_parallel_test(skel, prog, name);
			continue;
		}

		if (!libarena_is_test_prog(name))
			continue;

		if (!test__start_subtest(name))
			continue;

		run_libarena_test(skel, prog, name);
	}

out:
	libarena__destroy(skel);
}
