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

/*
 * testing lc_router_new() / lc_router_free()
 */

#include "test.h"
#include "falloc.h"
#include <librecast_pvt.h>
#include <librecast/router.h>

int main(void)
{
	lc_ctx_t *lctx;
	lc_router_t *r1, *r2;
	const unsigned int ports = 4;
	const int flags = -1;

	test_name("lc_router_new() / lc_router_free()");

	/* first, just create and free a router and context */
	lctx = lc_ctx_new();
	if (!test_assert(lctx != NULL, "lc_ctx_new()")) return test_status;
	r1 = lc_router_new(lctx, ports, flags);
	if (!test_assert(r1 != NULL, "lc_router_new()")) goto err_ctx_free;
	test_assert(r1->ctx == lctx, "router ctx set");
	test_assert(r1->ports == ports, "router ports set");
	test_assert(r1->flags == flags, "router flags set");
	lc_router_free(r1);
	lc_ctx_free(lctx);

	/* lc_ctx_free() should clean up router without needing explicit lc_router_free() */
	lctx = lc_ctx_new();
	if (!test_assert(lctx != NULL, "lc_ctx_new()")) return test_status;
	r1 = lc_router_new(lctx, ports, 0);
	if (!test_assert(r1 != NULL, "r1 allocated")) goto err_ctx_free;
	r2 = lc_router_new(lctx, ports, 0);
	if (!test_assert(r2 != NULL, "r2 allocated")) goto err_ctx_free;
	lc_ctx_free(lctx);

	/* Say bye to valgrind - it finds the things that happen next upsetting */
	if (RUNNING_ON_VALGRIND) return test_status;

	/* force ENOMEM */
	test_log("force ENOMEM\n");
	lctx = lc_ctx_new();
	if (!test_assert(lctx != NULL, "lc_ctx_new()")) return test_status;
	falloc_setfail(1);
	r1 = lc_router_new(lctx, ports, 0); /* will fail with ENOMEM */
	test_assert(errno == ENOMEM, "lc_router_new() - ENOMEM");
	test_assert(r1 == NULL, "lc_router_new() - ENOMEM, return NULL");
	falloc_setfail(FALLOC_NOFAIL);
	lc_ctx_free(lctx);

	/* force ENOMEM */
	test_log("force ENOMEM (router->port)\n");
	lctx = lc_ctx_new();
	if (!test_assert(lctx != NULL, "lc_ctx_new()")) return test_status;
	falloc_setfail(2);
	r1 = lc_router_new(lctx, ports, 0); /* will fail with ENOMEM */
	test_assert(errno == ENOMEM, "lc_router_new() - ENOMEM (port)");
	test_assert(r1 == NULL, "lc_router_new() - ENOMEM (port), return NULL");

err_ctx_free:
	lc_ctx_free(lctx);
	return test_status;
}
