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

/* testing lc_socket_listen() / lc_socket_listen_cancel() */

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

int main(void)
{
	lc_ctx_t *lctx = NULL;
	lc_socket_t *sock = NULL;
	lc_channel_t *chan = NULL;
	int rc = 0;

	test_name("lc_socket_listen() / lc_socket_listen_cancel()");
	test_require_net(TEST_NET_BASIC);

	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_ctx_free;
	chan = lc_channel_new(lctx, "example.com");
	if (!test_assert(chan != NULL, "lc_channel_new()")) goto err_ctx_free;

	rc = lc_channel_bind(sock, chan);
	if (!test_assert(rc == 0, "lc_channel_bind()")) goto err_ctx_free;
	rc = lc_channel_join(chan);
	if (!test_assert(rc == 0, "lc_channel_join()")) goto err_ctx_free;

	test_assert(lc_socket_listen(NULL, NULL, NULL) == LC_ERROR_SOCKET_REQUIRED,
			"lc_socket_listen requires socket");

	test_assert(lc_socket_listen(sock, NULL, NULL) == 0,
			"lc_socket_listen() returns 0 on success");

	test_assert(lc_socket_listen(sock, NULL, NULL) == LC_ERROR_SOCKET_LISTENING,
			"lc_socket_listen() returns LC_ERROR_SOCKET_LISTENING when socket busy");

	test_assert(lc_socket_listen_cancel(sock) == 0,
			"lc_socket_listen_cancel() returns 0 on success");

	test_assert(lc_socket_listen_cancel(sock) == 0,
			"lc_socket_listen_cancel() can be called twice");

err_ctx_free:
	if (rc) perror("error");
	lc_ctx_free(lctx);
	return test_status;
}
