// SPDX-License-Identifier: GPL-2.0
#include <api/fd/array.h>
#include <poll.h>
#include "util/debug.h"
#include "tests/tests.h"

static void fdarray__init_revents(struct fdarray *fda, short revents)
{
	int fd;

	fda->nr = fda->nr_alloc;

	for (fd = 0; fd < fda->nr; ++fd) {
		fda->entries[fd].fd	 = fda->nr - fd;
		fda->entries[fd].events  = revents;
		fda->entries[fd].revents = revents;
	}
}

static int fdarray__fprintf_prefix(struct fdarray *fda, const char *prefix, FILE *fp)
{
	int printed = 0;

	if (verbose <= 0)
		return 0;

	printed += fprintf(fp, "\n%s: ", prefix);
	return printed + fdarray__fprintf(fda, fp);
}

static int test__fdarray__filter(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
	int nr_fds, err = TEST_FAIL;
	struct fdarray *fda = fdarray__new(5, 5);

	if (fda == NULL) {
		pr_debug("\nfdarray__new() failed!");
		goto out;
	}

	fdarray__init_revents(fda, POLLIN);
	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
	if (nr_fds != fda->nr_alloc) {
		pr_debug("\nfdarray__filter()=%d != %d shouldn't have filtered anything",
			 nr_fds, fda->nr_alloc);
		goto out_delete;
	}

	fdarray__init_revents(fda, POLLHUP);
	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
	if (nr_fds != 0) {
		pr_debug("\nfdarray__filter()=%d != %d, should have filtered all fds",
			 nr_fds, fda->nr_alloc);
		goto out_delete;
	}

	fdarray__init_revents(fda, POLLHUP);
	fda->entries[2].revents = POLLIN;

	pr_debug("\nfiltering all but fda->entries[2]:");
	fdarray__fprintf_prefix(fda, "before", stderr);
	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
	fdarray__fprintf_prefix(fda, " after", stderr);
	if (nr_fds != 1) {
		pr_debug("\nfdarray__filter()=%d != 1, should have left just one event", nr_fds);
		goto out_delete;
	}

	fdarray__init_revents(fda, POLLHUP);
	fda->entries[0].revents = POLLIN;
	fda->entries[3].revents = POLLIN;

	pr_debug("\nfiltering all but (fda->entries[0], fda->entries[3]):");
	fdarray__fprintf_prefix(fda, "before", stderr);
	nr_fds = fdarray__filter(fda, POLLHUP, NULL, NULL);
	fdarray__fprintf_prefix(fda, " after", stderr);
	if (nr_fds != 2) {
		pr_debug("\nfdarray__filter()=%d != 2, should have left just two events",
			 nr_fds);
		goto out_delete;
	}

	pr_debug("\n");

	err = 0;
out_delete:
	fdarray__delete(fda);
out:
	return err;
}

static int test__fdarray__add(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
	int err = TEST_FAIL;
	struct fdarray *fda = fdarray__new(2, 2);

	if (fda == NULL) {
		pr_debug("\nfdarray__new() failed!");
		goto out;
	}

#define FDA_CHECK(_idx, _fd, _revents)					   \
	if (fda->entries[_idx].fd != _fd) {				   \
		pr_debug("\n%d: fda->entries[%d](%d) != %d!",		   \
			 __LINE__, _idx, fda->entries[1].fd, _fd);	   \
		goto out_delete;					   \
	}								   \
	if (fda->entries[_idx].events != (_revents)) {			   \
		pr_debug("\n%d: fda->entries[%d].revents(%d) != %d!",	   \
			 __LINE__, _idx, fda->entries[_idx].fd, _revents); \
		goto out_delete;					   \
	}

#define FDA_ADD(_idx, _fd, _revents, _nr)				   \
	if (fdarray__add(fda, _fd, _revents, fdarray_flag__default) < 0) { \
		pr_debug("\n%d: fdarray__add(fda, %d, %d) failed!",	   \
			 __LINE__,_fd, _revents);			   \
		goto out_delete;					   \
	}								   \
	if (fda->nr != _nr) {						   \
		pr_debug("\n%d: fdarray__add(fda, %d, %d)=%d != %d",	   \
			 __LINE__,_fd, _revents, fda->nr, _nr);		   \
		goto out_delete;					   \
	}								   \
	FDA_CHECK(_idx, _fd, _revents)

	FDA_ADD(0, 1, POLLIN, 1);
	FDA_ADD(1, 2, POLLERR, 2);

	fdarray__fprintf_prefix(fda, "before growing array", stderr);

	FDA_ADD(2, 35, POLLHUP, 3);

	if (fda->entries == NULL) {
		pr_debug("\nfdarray__add(fda, 35, POLLHUP) should have allocated fda->pollfd!");
		goto out_delete;
	}

	fdarray__fprintf_prefix(fda, "after 3rd add", stderr);

	FDA_ADD(3, 88, POLLIN | POLLOUT, 4);

	fdarray__fprintf_prefix(fda, "after 4th add", stderr);

	FDA_CHECK(0, 1, POLLIN);
	FDA_CHECK(1, 2, POLLERR);
	FDA_CHECK(2, 35, POLLHUP);
	FDA_CHECK(3, 88, POLLIN | POLLOUT);

#undef FDA_ADD
#undef FDA_CHECK

	pr_debug("\n");

	err = 0;
out_delete:
	fdarray__delete(fda);
out:
	return err;
}

DEFINE_SUITE("Filter fds with revents mask in a fdarray", fdarray__filter);
DEFINE_SUITE("Add fd to a fdarray, making it autogrow", fdarray__add);
