/* Copyright (c) 2024 Nordic Semiconductor ASA
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/atomic_builtin.h>
#include <zephyr/sys/atomic_types.h>

#include <testlib/conn.h>
#include <testlib/scan.h>

#include <bs_tracing.h>
#include <bstests.h>

extern enum bst_result_t bst_result;

LOG_MODULE_REGISTER(dut, LOG_LEVEL_INF);

atomic_t connected_count;

static void on_connected(struct bt_conn *conn, uint8_t conn_err)
{
	atomic_t count = atomic_inc(&connected_count) + 1;

	LOG_INF("Connected. Current count %d", count);
}

static void on_disconnected(struct bt_conn *conn, uint8_t reason)
{
	atomic_t count = atomic_dec(&connected_count) - 1;

	LOG_INF("Disconnected. Current count %d", count);
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected = on_connected,
	.disconnected = on_disconnected,
};

static void disconnect_all(void)
{
	for (size_t i = 0; i < CONFIG_BT_MAX_CONN; i++) {
		int err;
		struct bt_conn *conn = bt_testlib_conn_unindex(BT_CONN_TYPE_LE, i);

		if (conn) {
			err = bt_testlib_disconnect(&conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
			__ASSERT_NO_MSG(!err);
		}
	}
}

int main(void)
{
	int err;
	bt_addr_le_t connectable_addr;
	struct bt_conn *conn = NULL;

	bst_result = In_progress;

	err = bt_enable(NULL);
	__ASSERT_NO_MSG(!err);

	err = bt_set_name("dut");
	__ASSERT_NO_MSG(!err);

	struct bt_data ad[1] = {0};

	const char *dev_name = bt_get_name();

	ad[0].type = BT_DATA_NAME_COMPLETE;
	ad[0].data_len = strlen(dev_name);
	ad[0].data = (const uint8_t *)dev_name;

	LOG_INF("---------- Test setup ----------");

	LOG_INF("Environment test: Advertiser fills connection capacity.");

	/* `bt_le_adv_start` is invoked once, and.. */

	err = bt_le_adv_start(BT_LE_ADV_CONN, NULL, 0, NULL, 0);
	__ASSERT_NO_MSG(!err);

	err = bt_le_adv_update_data(ad, 1, NULL, 0);
	__ASSERT_NO_MSG(!err);

	/* .. the advertiser shall autoresume. Since it's not
	 * stopped, it shall continue receivng connections until
	 * the stack runs out of connection objects.
	 */

	LOG_INF("Waiting for connections...");
	while (atomic_get(&connected_count) < CONFIG_BT_MAX_CONN) {
		k_msleep(1000);
	}

	LOG_INF("Environment test done");

	LOG_INF("Environment test: Disconnect one to see that it comes back");

	/* Disconnect one of the connections. It does matter
	 * which, but object with index 0 is chosen for
	 * simplicity.
	 */

	conn = bt_testlib_conn_unindex(BT_CONN_TYPE_LE, 0);
	__ASSERT_NO_MSG(conn);

	/* Disconnect, but wait with calling unref.. */

	err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
	__ASSERT_NO_MSG(!err);
	bt_testlib_wait_disconnected(conn);

	/* Simulate a delayed unref. We delay to make sure the resume is not
	 * triggered by disconnection, but by a connection object becoming
	 * available.
	 */

	k_sleep(K_SECONDS(10));

	bt_testlib_conn_unref(&conn);

	/* Since there is a free connection object again, the
	 * advertiser shall automatically resume and receive a
	 * new connection.
	 */

	LOG_INF("Waiting for connections...");
	while (atomic_get(&connected_count) < CONFIG_BT_MAX_CONN) {
		k_msleep(1000);
	}

	LOG_INF("Environment test done");


	LOG_INF("Clean up");

	err = bt_le_adv_stop();
	__ASSERT_NO_MSG(!err);

	disconnect_all();

	LOG_INF("Cleanup done");


	LOG_INF("Setup step: Connect one central connection");

	err = bt_testlib_scan_find_name(&connectable_addr, "connectable");
	__ASSERT_NO_MSG(!err);

	err = bt_testlib_connect(&connectable_addr, &conn);
	__ASSERT_NO_MSG(!err);

	LOG_INF("Setup step done");


	LOG_INF("Setup step: Start advertiser. Let it fill the connection limit.");

	/* With one connection slot taken by the central role, we fill the rest. */

	err = bt_le_adv_start(BT_LE_ADV_CONN, NULL, 0, NULL, 0);
	__ASSERT_NO_MSG(!err);

	err = bt_le_adv_update_data(ad, 1, NULL, 0);
	__ASSERT_NO_MSG(!err);

	LOG_INF("Waiting for connections...");
	while (atomic_get(&connected_count) < CONFIG_BT_MAX_CONN) {
		k_sleep(K_SECONDS(1));
	}

	LOG_INF("Setup step done");


	LOG_INF("---------- Test start ----------");

	LOG_INF("Disconnect, wait and connect the central connection.");

	/* In this situation, disconnecting the central role should not allow
	 * the advertiser to resume. This behavior was introduced in 6a79c3deae.
	 */

	LOG_INF("Poke: Disconnect");
	err = bt_testlib_disconnect(&conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
	__ASSERT_NO_MSG(!err);

	LOG_INF("Poke: Wait to bait the advertiser");
	k_sleep(K_SECONDS(5));

	LOG_INF("Observe: Connect");
	err = bt_testlib_connect(&connectable_addr, &conn);
	if (err) {
		/* If the test fails, it's because the advertiser 'stole' the
		 * central's connection slot.
		 */
		__ASSERT_NO_MSG(err == -ENOMEM);

		LOG_ERR("Fault: Advertiser stole the connection slot");
		bs_trace_silent_exit(1);
	}

	bst_result = Passed;
	LOG_INF("Test passed");
	bs_trace_silent_exit(0);

	return 0;
}
