/*
 * Copyright (c) 2020 Demant
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/types.h>
#include <zephyr/ztest.h>
#include "kconfig.h"

#define ULL_LLCP_UNITTEST

#include <zephyr/bluetooth/hci.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/slist.h>
#include <zephyr/sys/util.h>
#include "hal/ccm.h"

#include "util/util.h"
#include "util/mem.h"
#include "util/memq.h"
#include "util/dbuf.h"

#include "pdu.h"
#include "ll.h"
#include "ll_settings.h"

#include "lll.h"
#include "lll/lll_df_types.h"
#include "lll_conn.h"
#include "lll_conn_iso.h"

#include "ull_tx_queue.h"

#include "isoal.h"
#include "ull_iso_types.h"
#include "ull_conn_iso_types.h"

#include "ull_conn_types.h"
#include "ull_llcp.h"
#include "ull_conn_internal.h"
#include "ull_llcp_internal.h"

#include "helper_pdu.h"
#include "helper_util.h"


static struct ll_conn conn[CONFIG_BT_CTLR_LLCP_CONN];

static void setup(void)
{
	ull_conn_init();
	test_setup(&conn[0]);
}
void test_tx_buffer_alloc(void)
{
	struct proc_ctx *ctxs[CONFIG_BT_CTLR_LLCP_CONN];
	struct node_tx *tx[CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM +
		CONFIG_BT_CTLR_LLCP_CONN * CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM + 3];
	uint16_t tx_alloc_idx = 0;
	int i;

	for (int ctx_idx = 0; ctx_idx < CONFIG_BT_CTLR_LLCP_CONN; ctx_idx++) {
		ctxs[ctx_idx] = llcp_create_local_procedure(PROC_VERSION_EXCHANGE);
	}

	/* Init per conn tx_buffer_alloc count */
	for (int j = 1; j < CONFIG_BT_CTLR_LLCP_CONN; j++) {
		conn[j].llcp.tx_buffer_alloc = 0;
	}
#if defined(LLCP_TX_CTRL_BUF_QUEUE_ENABLE)
	/* Check alloc flow */
	for (i = 0; i < CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM; i++) {
		zassert_true(llcp_tx_alloc_peek(&conn[0], ctxs[0]), NULL);
		tx[tx_alloc_idx] = llcp_tx_alloc(&conn[0], ctxs[0]);
		zassert_equal(conn[0].llcp.tx_buffer_alloc, i + 1, NULL);
		zassert_equal(common_tx_buffer_alloc_count(), 0, NULL);
		zassert_not_null(tx[tx_alloc_idx], NULL);
		tx_alloc_idx++;
	}
	for (i = 0; i < CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM; i++) {
		zassert_true(llcp_tx_alloc_peek(&conn[0], ctxs[0]), NULL);
		tx[tx_alloc_idx] = llcp_tx_alloc(&conn[0], ctxs[0]);
		zassert_equal(conn[0].llcp.tx_buffer_alloc,
			      CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM + i + 1, NULL);
		zassert_equal(common_tx_buffer_alloc_count(), i+1, NULL);
		zassert_not_null(tx[tx_alloc_idx], NULL);
		tx_alloc_idx++;
	}
	zassert_false(llcp_tx_alloc_peek(&conn[0], ctxs[0]), NULL);
	zassert_equal(ctxs[0]->wait_reason, WAITING_FOR_TX_BUFFER, NULL);

	for (int j = 1; j < CONFIG_BT_CTLR_LLCP_CONN; j++) {
		/* Now global pool is exausted, but conn pool is not */
		for (i = 0; i < CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM; i++) {
			zassert_true(llcp_tx_alloc_peek(&conn[j], ctxs[j]), NULL);
			tx[tx_alloc_idx] = llcp_tx_alloc(&conn[j], ctxs[j]);
			zassert_not_null(tx[tx_alloc_idx], NULL);
			zassert_equal(common_tx_buffer_alloc_count(),
				      CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM, NULL);
			zassert_equal(conn[j].llcp.tx_buffer_alloc, i + 1, NULL);
			tx_alloc_idx++;
		}

		zassert_false(llcp_tx_alloc_peek(&conn[j], ctxs[j]), NULL);
		zassert_equal(ctxs[j]->wait_reason, WAITING_FOR_TX_BUFFER, NULL);
	}

	ull_cp_release_tx(&conn[0], tx[1]);
	zassert_equal(common_tx_buffer_alloc_count(),
		      CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM - 1, NULL);
	zassert_equal(conn[0].llcp.tx_buffer_alloc, CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM +
		      CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM - 1, NULL);

	/* global pool is now 'open' again, but ctxs[1] is NOT next in line */
	zassert_false(llcp_tx_alloc_peek(&conn[1], ctxs[1]), NULL);

	/* ... ctxs[0] is */
	zassert_true(llcp_tx_alloc_peek(&conn[0], ctxs[0]), NULL);
	tx[tx_alloc_idx] = llcp_tx_alloc(&conn[0], ctxs[0]);
	zassert_equal(common_tx_buffer_alloc_count(), CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM,
		      NULL);
	zassert_equal(conn[0].llcp.tx_buffer_alloc, CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM +
		      CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM, NULL);

	zassert_not_null(tx[tx_alloc_idx], NULL);
	tx_alloc_idx++;
	ull_cp_release_tx(&conn[0], tx[tx_alloc_idx - 1]);
	zassert_equal(common_tx_buffer_alloc_count(),
		      CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM - 1, NULL);
	zassert_equal(conn[0].llcp.tx_buffer_alloc, CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM +
		      CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM - 1, NULL);

	/* global pool does not allow as ctxs[2] is NOT next up */
	zassert_false(llcp_tx_alloc_peek(&conn[2], ctxs[2]), NULL);

#if (CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM > 0)
	/* Release conn[2] held tx, to confirm alloc is allowed after releasing pre-alloted buf */
	zassert_true(!(conn[2].llcp.tx_buffer_alloc <
		       CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM), NULL);
	ull_cp_release_tx(&conn[2], tx[CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM +
			  CONFIG_BT_CTLR_LLCP_COMMON_TX_CTRL_BUF_NUM +
			  CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM]);
	zassert_true((conn[2].llcp.tx_buffer_alloc <
		       CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM), NULL);

	/* global pool does not allow as ctxs[2] is not next up, but pre alloted is now avail */
	zassert_equal(ctxs[2]->wait_reason, WAITING_FOR_TX_BUFFER, NULL);
	zassert_not_null(ctxs[2]->wait_node.next, NULL);
	zassert_true(llcp_tx_alloc_peek(&conn[2], ctxs[2]), NULL);
	tx[tx_alloc_idx] = llcp_tx_alloc(&conn[2], ctxs[2]);
	zassert_not_null(tx[tx_alloc_idx], NULL);
	tx_alloc_idx++;

	/* No longer waiting in line */
	zassert_equal(ctxs[2]->wait_reason, WAITING_FOR_NOTHING, NULL);
	zassert_is_null(ctxs[2]->wait_node.next, NULL);
#endif /* (CONFIG_BT_CTLR_LLCP_PER_CONN_TX_CTRL_BUF_NUM > 0) */

	/* now ctxs[1] is next up */
	zassert_true(llcp_tx_alloc_peek(&conn[1], ctxs[1]), NULL);
	tx[tx_alloc_idx] = llcp_tx_alloc(&conn[0], ctxs[0]);
	zassert_not_null(tx[tx_alloc_idx], NULL);
	tx_alloc_idx++;

#else /* LLCP_TX_CTRL_BUF_QUEUE_ENABLE */
	/* Test that there are exactly LLCP_CONN * LLCP_TX_CTRL_BUF_NUM_MAX
	 * buffers available
	 */
	for (i = 0;
	     i < CONFIG_BT_CTLR_LLCP_TX_PER_CONN_TX_CTRL_BUF_NUM_MAX * CONFIG_BT_CTLR_LLCP_CONN;
	     i++) {
		zassert_true(llcp_tx_alloc_peek(&conn[0], ctxs[0]), NULL);
		tx[tx_alloc_idx] = llcp_tx_alloc(&conn[0], ctxs[0]);
		zassert_not_null(tx[tx_alloc_idx], NULL);
		tx_alloc_idx++;
	}
	zassert_false(llcp_tx_alloc_peek(&conn[0], ctxs[0]), NULL);
#endif /* LLCP_TX_CTRL_BUF_QUEUE_ENABLE */
}

void test_main(void)
{
	ztest_test_suite(
		tx_buffer_alloc, ztest_unit_test_setup_teardown(test_tx_buffer_alloc, setup,
								unit_test_noop));

	ztest_run_test_suite(tx_buffer_alloc);
}
