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

#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include <zephyr/kernel.h>

#include <zephyr/sys/printk.h>

#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>

#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(bt_bsim_privacy, LOG_LEVEL_INF);

#include "bs_types.h"
#include "bs_tracing.h"
#include "bstests.h"
#include "bs_cmd_line.h"

#define FAIL(...)                                                                                  \
	do {                                                                                       \
		bst_result = Failed;                                                               \
		bs_trace_error_time_line(__VA_ARGS__);                                             \
	} while (0)

#define PASS(...)                                                                                  \
	do {                                                                                       \
		bst_result = Passed;                                                               \
		bs_trace_info_time(1, __VA_ARGS__);                                                \
	} while (0)

extern enum bst_result_t bst_result;

#define CREATE_FLAG(flag) static atomic_t flag = (atomic_t) false
#define SET_FLAG(flag)	  (void)atomic_set(&flag, (atomic_t) true)
#define GET_FLAG(flag)	  (bool)atomic_get(&flag)
#define UNSET_FLAG(flag)  (void)atomic_set(&flag, (atomic_t) false)
#define WAIT_FOR_FLAG(flag)                                                                        \
	while (!(bool)atomic_get(&flag)) {                                                         \
		(void)k_sleep(K_MSEC(1));                                                          \
	}

CREATE_FLAG(paired_flag);
CREATE_FLAG(connected_flag);
CREATE_FLAG(wait_disconnection);
CREATE_FLAG(wait_scanned);

static struct bt_conn *default_conn;

enum adv_param_t {
	CONN_SCAN,
	CONN_NSCAN,
	NCONN_SCAN,
	NCONN_NSCAN,
};

enum addr_type_t {
	RPA,
	IDENTITY_ADDR,
};

static enum addr_type_t test_addr_type;

static bool use_ext_adv;

static bool scannable_test;
static bool connectable_test;
static enum adv_param_t adv_param;

static int sim_id;

void peripheral_test_args_parse(int argc, char *argv[])
{
	char *addr_type_arg = NULL;

	bs_args_struct_t args_struct[] = {
		{
			.dest = &sim_id,
			.type = 'i',
			.name = "{positive integer}",
			.option = "sim-id",
			.descript = "Simulation ID counter",
		},
		{
			.dest = &addr_type_arg,
			.type = 's',
			.name = "{identity, rsa}",
			.option = "addr-type",
			.descript = "Address type to test",
		},
		{
			.dest = &use_ext_adv,
			.type = 'b',
			.name = "{0, 1}",
			.option = "use-ext-adv",
			.descript = "Use Extended Advertising",
		},
		{
			.dest = &scannable_test,
			.type = 'b',
			.name = "{0, 1}",
			.option = "scannable",
			.descript = "Use a scannable advertiser for the test",
		},
		{
			.dest = &connectable_test,
			.type = 'b',
			.name = "{0, 1}",
			.option = "connectable",
			.descript = "Use a connectable advertiser for the test",
		},
	};

	bs_args_parse_all_cmd_line(argc, argv, args_struct);

	if (addr_type_arg != NULL) {
		if (!strcmp(addr_type_arg, "identity")) {
			test_addr_type = IDENTITY_ADDR;
		} else if (!strcmp(addr_type_arg, "rpa")) {
			test_addr_type = RPA;
		}
	}

	if (connectable_test && scannable_test) {
		if (!use_ext_adv) {
			adv_param = CONN_SCAN;
		}
	} else if (connectable_test) {
		adv_param = CONN_NSCAN;
	} else if (scannable_test) {
		adv_param = NCONN_SCAN;
	} else {
		adv_param = NCONN_NSCAN;
	}
}

static void wait_for_scanned(void)
{
	LOG_DBG("Waiting for scan request");
	WAIT_FOR_FLAG(wait_scanned);
	UNSET_FLAG(wait_scanned);
}

static void adv_scanned_cb(struct bt_le_ext_adv *adv, struct bt_le_ext_adv_scanned_info *info)
{
	LOG_DBG("Scan request received");
	SET_FLAG(wait_scanned);
}

static struct bt_le_ext_adv_cb adv_cb = {
	.scanned = adv_scanned_cb,
};

static void create_adv(struct bt_le_ext_adv **adv)
{
	int err;
	struct bt_le_adv_param params;

	memset(&params, 0, sizeof(struct bt_le_adv_param));

	params.options |= BT_LE_ADV_OPT_CONNECTABLE;

	params.id = BT_ID_DEFAULT;
	params.sid = 0;
	params.interval_min = BT_GAP_ADV_SLOW_INT_MIN;
	params.interval_max = BT_GAP_ADV_SLOW_INT_MAX;

	err = bt_le_ext_adv_create(&params, &adv_cb, adv);
	if (err) {
		LOG_ERR("Failed to create advertiser (%d)", err);
		return;
	}

	LOG_DBG("Advertiser created");
}

static void update_adv_params(struct bt_le_ext_adv *adv, enum adv_param_t adv_params,
			      enum addr_type_t addr_type)
{
	int err;
	struct bt_le_adv_param params;

	memset(&params, 0, sizeof(struct bt_le_adv_param));

	if (adv_params == CONN_SCAN) {
		params.options |= BT_LE_ADV_OPT_CONNECTABLE;
		params.options |= BT_LE_ADV_OPT_SCANNABLE;
		LOG_DBG("Advertiser params: CONN_SCAN");
	} else if (adv_params == CONN_NSCAN) {
		params.options |= BT_LE_ADV_OPT_CONNECTABLE;
		LOG_DBG("Advertiser params: CONN_NSCAN");
	} else if (adv_params == NCONN_SCAN) {
		params.options |= BT_LE_ADV_OPT_SCANNABLE;
		LOG_DBG("Advertiser params: NCONN_SCAN");
	} else if (adv_params == NCONN_NSCAN) {
		LOG_DBG("Advertiser params: NCONN_NSCAN");
	}

	if (use_ext_adv) {
		params.options |= BT_LE_ADV_OPT_EXT_ADV;
		LOG_DBG("Advertiser params: EXT_ADV");
		params.options |= BT_LE_ADV_OPT_NOTIFY_SCAN_REQ;
		LOG_DBG("Advertiser params: NOTIFY_SCAN_REQ");
	} else {
		LOG_DBG("Advertiser params: LEGACY_ADV");
	}

	if (addr_type == IDENTITY_ADDR) {
		LOG_DBG("Advertiser params: USE_IDENTITY");
		params.options |= BT_LE_ADV_OPT_USE_IDENTITY;
	} else if (addr_type == RPA) {
		LOG_DBG("Advertiser params: USE_RPA");
	}

	params.id = BT_ID_DEFAULT;
	params.sid = 0;
	params.interval_min = BT_GAP_ADV_SLOW_INT_MIN;
	params.interval_max = BT_GAP_ADV_SLOW_INT_MAX;

	err = bt_le_ext_adv_update_param(adv, &params);
	if (err) {
		LOG_ERR("Failed to update advertiser set (%d)", err);
		return;
	}

	if (use_ext_adv && adv_params == NCONN_SCAN) {
		uint8_t data[4] = {0x61, 0x6c, 0x65, 0x64};
		struct bt_data sd;
		size_t sd_len = 1;

		sd.type = 0x09;
		sd.data_len = 0x05;
		sd.data = data;

		err = bt_le_ext_adv_set_data(adv, NULL, 0, &sd, sd_len);
		if (err) {
			LOG_ERR("Failed to set advertising data (%d)", err);
		}

		LOG_DBG("Advertiser data set");
	}

	LOG_DBG("Advertiser params updated");
}

static void start_adv(struct bt_le_ext_adv *adv)
{
	int err;
	int32_t timeout = 0;
	uint8_t num_events = 0;

	struct bt_le_ext_adv_start_param start_params;

	start_params.timeout = timeout;
	start_params.num_events = num_events;

	err = bt_le_ext_adv_start(adv, &start_params);

	if (err) {
		LOG_ERR("Failed to start advertiser (%d)", err);
		return;
	}

	LOG_DBG("Advertiser started");
}

static void stop_adv(struct bt_le_ext_adv *adv)
{
	int err;

	err = bt_le_ext_adv_stop(adv);
	if (err) {
		LOG_WRN("Failed to stop advertiser (%d)", err);
		return;
	}

	LOG_DBG("Advertiser stopped");
}

static void disconnect(void)
{
	LOG_DBG("Starting disconnection");
	int err;

	err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
	if (err) {
		FAIL("Disconnection failed (err %d)\n", err);
	}

	WAIT_FOR_FLAG(wait_disconnection);
	UNSET_FLAG(wait_disconnection);
}

static void wait_for_connection(void)
{
	WAIT_FOR_FLAG(connected_flag);
	UNSET_FLAG(connected_flag);
}

static void connected(struct bt_conn *conn, uint8_t err)
{
	LOG_DBG("Peripheral Connected function");

	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	if (err) {
		LOG_WRN("Failed to connect to %s (%u)", addr, err);
		return;
	}

	LOG_DBG("Connected: %s", addr);

	default_conn = bt_conn_ref(conn);

	if (!GET_FLAG(paired_flag)) {
		if (bt_conn_set_security(conn, BT_SECURITY_L2)) {
			FAIL("Failed to set security\n");
		}
	} else {
		SET_FLAG(connected_flag);
	}
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	char addr[BT_ADDR_LE_STR_LEN];

	if (conn != default_conn) {
		return;
	}

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	LOG_DBG("Disconnected: %s (reason 0x%02x)", addr, reason);

	bt_conn_unref(default_conn);
	default_conn = NULL;

	LOG_DBG("Disconnected");
	SET_FLAG(wait_disconnection);
}

static void identity_resolved(struct bt_conn *conn, const bt_addr_le_t *rpa,
			      const bt_addr_le_t *identity)
{
	char addr_identity[BT_ADDR_LE_STR_LEN];
	char addr_rpa[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(identity, addr_identity, sizeof(addr_identity));
	bt_addr_le_to_str(rpa, addr_rpa, sizeof(addr_rpa));

	LOG_DBG("Identity resolved %s -> %s", addr_rpa, addr_identity);
}

static void security_changed(struct bt_conn *conn, bt_security_t level, enum bt_security_err err)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	if (!err) {
		LOG_DBG("Security changed: %s level %u", addr, level);
	} else {
		LOG_ERR("Security failed: %s level %u err %d", addr, level);
	}
}

static void pairing_complete(struct bt_conn *conn, bool bonded)
{
	LOG_DBG("Pairing complete");
	SET_FLAG(paired_flag);
}

static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason)
{
	LOG_WRN("Pairing failed (%d). Disconnecting.", reason);
	bt_conn_disconnect(conn, BT_HCI_ERR_AUTH_FAIL);
}

static struct bt_conn_cb peri_cb;

static struct bt_conn_auth_info_cb auth_cb_info = {
	.pairing_complete = pairing_complete,
	.pairing_failed = pairing_failed,
};

static void test_peripheral_main(void)
{
	LOG_DBG("Peripheral device");

	int err;
	struct bt_le_ext_adv *adv = NULL;

	peri_cb.connected = connected;
	peri_cb.disconnected = disconnected;
	peri_cb.security_changed = security_changed;
	peri_cb.identity_resolved = identity_resolved;

	bt_conn_cb_register(&peri_cb);

	err = bt_enable(NULL);
	if (err) {
		FAIL("Bluetooth init failed (err %d)\n", err);
	}

	LOG_DBG("Bluetooth initialized");

	bt_conn_auth_info_cb_register(&auth_cb_info);

	create_adv(&adv);

	update_adv_params(adv, CONN_NSCAN, RPA);
	start_adv(adv);

	WAIT_FOR_FLAG(paired_flag);

	disconnect();
	stop_adv(adv);

	update_adv_params(adv, adv_param, test_addr_type);
	start_adv(adv);

	/* (the connection with identity should fail with privacy network mode) */
	if (connectable_test) {
		wait_for_connection();
		disconnect();
	} else if (scannable_test && use_ext_adv) {
		wait_for_scanned();
	}

	/* It is up to the controller to decide if it should send an
	 * AUX_SCAN_RSP or not when it gets ordered to stop advertising right
	 * after receiving the AUX_SCAN_REQ.
	 *
	 * Some test cases depend on receiving AUX_SCAN_RSP, so don't stop the
	 * advertiser. This ensures we will always get it.
	 */
}

void test_peripheral(void)
{
	char *addr_tested = "";

	if (test_addr_type == RPA) {
		addr_tested = "RPA";
	} else if (test_addr_type == IDENTITY_ADDR) {
		addr_tested = "identity address";
	}

	LOG_INF("Peripheral test START (id: %d: %s advertiser, "
		"%sconnectable %sscannable, testing %s)\n",
		sim_id, use_ext_adv ? "extended" : "legacy", connectable_test ? "" : "non-",
		scannable_test ? "" : "non-", addr_tested);

	test_peripheral_main();

	PASS("passed\n");
}
