/* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only */
/* Copyright (c) 2024 Brett Sheffield <bacs@librecast.net> */

/* test 0190 Socket OIL Filter tests */

#include "test.h"
#include "testnet.h"
#include <librecast/net.h>
#include <librecast_pvt.h>

#define CHANNELS 4

int main(void)
{
	lc_ctx_t *lctx;
	lc_socket_t *sock;
	lc_channel_t *chan[CHANNELS];

	test_name("Socket OIL Filter");
	test_require_net(TEST_NET_BASIC);

	/* create ctx, socket and some random channels */
	lctx = lc_ctx_new();
	if (!test_assert(lctx != NULL, "lc_ctx_new()")) return test_status;
	sock = lc_socket_new(lctx);
	if (!test_assert(sock != NULL, "lc_socket_new()")) goto err_free_lctx;
	for (int i = 0; i < CHANNELS; i++) {
		chan[i] = lc_channel_random(lctx);
		if (!chan[i] || lc_channel_bind(sock, chan[i])) goto err_free_lctx;
	}

	/* join channels (except last), adding them to the OIL filter */
	test_assert(sock->oil == NULL, "OIL filter is NULL");
	for (int i = 0; i < CHANNELS - 1; i++) {
		if (!test_assert(lc_channel_join(chan[i]) == 0, "lc_channel_join()[%i]", i))
			goto err_free_lctx;
	}
	test_assert(sock->oil != NULL, "OIL filter is allocated");

	for (int i = 0; i < CHANNELS - 1; i++) {
		test_assert(lc_socket_oil_cmp(sock, chan[i]->hash) == 0, "lc_socket_oil_cmp()[%i]", i);
	}
	/* this last group was not added, ensure not found */
	test_assert(lc_socket_oil_cmp(sock, chan[CHANNELS - 1]->hash) == -1,
			"lc_socket_oil_cmp() - check for hash not in filter");
	test_assert(errno == ENOENT, "ENOENT");

	/* PART channels, ensure hashes removed from OIL filter */
	for (int i = 0; i < CHANNELS - 1; i++) {
		if (!test_assert(lc_channel_part(chan[i]) == 0, "lc_channel_part()[%i]", i))
			goto err_free_lctx;
		errno = 0;
		test_assert(lc_socket_oil_cmp(sock, chan[i]->hash) == -1,
				"lc_socket_oil_cmp()[%i] ensure channel removed", i);
		test_assert(errno == ENOENT, "errno = ENOENT");
	}

err_free_lctx:
	lc_ctx_free(lctx);
	return test_status;
}
