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

#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/__assert.h>

#include <zephyr/net/buf.h>
#include <zephyr/bluetooth/buf.h>

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

#include "common/bt_str.h"

#include "host/conn_internal.h"
#include "host/l2cap_internal.h"

#include "utils.h"
#include "common.h"
#include "bstests.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_tinyhost, 3);

DEFINE_FLAG(is_connected);
DEFINE_FLAG(flag_l2cap_connected);
DEFINE_FLAG(flag_data_length_updated);

static K_FIFO_DEFINE(rx_queue);

#define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE)
NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, CONFIG_BT_BUF_CMD_TX_COUNT,
			  CMD_BUF_SIZE, 8, NULL);

static K_SEM_DEFINE(cmd_sem, 1, 1);
static struct k_sem acl_pkts;
static struct k_sem tx_credits;
static uint16_t peer_mps;
static uint16_t conn_handle;

static uint16_t active_opcode = 0xFFFF;
static struct net_buf *cmd_rsp;

struct net_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len)
{
	struct bt_hci_cmd_hdr *hdr;
	struct net_buf *buf;

	LOG_DBG("opcode 0x%04x param_len %u", opcode, param_len);

	buf = net_buf_alloc(&hci_cmd_pool, K_FOREVER);
	__ASSERT_NO_MSG(buf);

	LOG_DBG("buf %p", buf);

	net_buf_reserve(buf, BT_BUF_RESERVE);

	bt_buf_set_type(buf, BT_BUF_CMD);

	hdr = net_buf_add(buf, sizeof(*hdr));
	hdr->opcode = sys_cpu_to_le16(opcode);
	hdr->param_len = param_len;

	return buf;
}

static void handle_cmd_complete(struct net_buf *buf)
{
	struct bt_hci_evt_hdr *hdr;
	uint8_t status, ncmd;
	uint16_t opcode;

	struct net_buf_simple_state state;

	net_buf_simple_save(&buf->b, &state);

	hdr = net_buf_pull_mem(buf, sizeof(*hdr));

	if (hdr->evt == BT_HCI_EVT_CMD_COMPLETE) {
		struct bt_hci_evt_cmd_complete *evt;

		evt = net_buf_pull_mem(buf, sizeof(*evt));
		status = 0;
		ncmd = evt->ncmd;
		opcode = sys_le16_to_cpu(evt->opcode);

	} else if (hdr->evt == BT_HCI_EVT_CMD_STATUS) {
		struct bt_hci_evt_cmd_status *evt;

		evt = net_buf_pull_mem(buf, sizeof(*evt));
		status = buf->data[0];
		ncmd = evt->ncmd;
		opcode = sys_le16_to_cpu(evt->opcode);

	} else {
		__ASSERT_NO_MSG(0);
	}

	LOG_DBG("opcode 0x%04x status %x", opcode, status);

	__ASSERT(status == 0x00, "cmd status: %x", status);

	__ASSERT(active_opcode == opcode, "unexpected opcode %x != %x", active_opcode, opcode);

	if (active_opcode) {
		active_opcode = 0xFFFF;
		cmd_rsp = net_buf_ref(buf);
		net_buf_simple_restore(&buf->b, &state);
	}

	if (ncmd) {
		k_sem_give(&cmd_sem);
	}
}

static void handle_meta_event(struct net_buf *buf)
{
	uint8_t code = buf->data[2];

	switch (code) {
	case BT_HCI_EVT_LE_ENH_CONN_COMPLETE:
	case BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2:
		conn_handle = sys_get_le16(&buf->data[4]);
		LOG_DBG("connected: handle: %d", conn_handle);
		SET_FLAG(is_connected);
		break;
	case BT_HCI_EVT_LE_DATA_LEN_CHANGE:
		SET_FLAG(flag_data_length_updated);
		break;
	case BT_HCI_EVT_LE_CHAN_SEL_ALGO:
		/* do nothing */
		break;
	default:
		LOG_ERR("unhandled meta event %x", code);
		LOG_HEXDUMP_ERR(buf->data, buf->len, "HCI META EVT");
	}
}

static void handle_ncp(struct net_buf *buf)
{
	struct bt_hci_evt_hdr *hdr;

	hdr = net_buf_pull_mem(buf, sizeof(*hdr));

	struct bt_hci_evt_num_completed_packets *evt = (void *)buf->data;

	uint16_t handle, count;

	handle = sys_le16_to_cpu(evt->h[0].handle);
	count = sys_le16_to_cpu(evt->h[0].count);

	LOG_DBG("sent %d packets", count);

	while (count--) {
		k_sem_give(&acl_pkts);
	}
}

static void handle_l2cap_credits(struct net_buf *buf)
{
	struct bt_l2cap_le_credits *ev = (void *)buf->data;
	uint16_t credits = sys_le16_to_cpu(ev->credits);

	LOG_DBG("got credits: %d", credits);
	while (credits--) {
		k_sem_give(&tx_credits);
	}
}

static void handle_l2cap_connected(struct net_buf *buf)
{
	struct bt_l2cap_le_conn_rsp *rsp = (void *)buf->data;

	uint16_t credits = sys_le16_to_cpu(rsp->credits);
	uint16_t mtu = sys_le16_to_cpu(rsp->mtu);
	uint16_t mps = sys_le16_to_cpu(rsp->mps);

	peer_mps = mps;

	LOG_DBG("l2cap connected: mtu %d mps %d credits: %d", mtu, mps, credits);

	k_sem_init(&tx_credits, credits, credits);
	SET_FLAG(flag_l2cap_connected);
}

static void handle_sig(struct net_buf *buf)
{
	struct bt_l2cap_sig_hdr *hdr;

	hdr = net_buf_pull_mem(buf, sizeof(*hdr));

	switch (hdr->code) {
	case BT_L2CAP_LE_CONN_RSP:
		handle_l2cap_connected(buf);
		return;
	case BT_L2CAP_LE_CREDITS:
		handle_l2cap_credits(buf);
		return;
	case BT_L2CAP_DISCONN_REQ:
		FAIL("channel disconnected\n");
		return;
	default:
		FAIL("unhandled opcode %x\n", hdr->code);
		return;
	}
}

static void handle_l2cap(struct net_buf *buf)
{
	struct bt_l2cap_hdr *hdr;
	uint16_t cid;

	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
	cid = sys_le16_to_cpu(hdr->cid);

	__ASSERT_NO_MSG(buf->len == hdr->len);
	LOG_DBG("Packet for CID %u len %u", cid, buf->len);
	LOG_HEXDUMP_DBG(buf->data, buf->len, "l2cap");

	/* signaling PDU */
	if (cid == 0x0005) {
		handle_sig(buf);
		return;
	}

	/* CoC PDU */
	if (cid == 0x0040) {
		FAIL("unexpected data rx");
	}
}

static void handle_acl(struct net_buf *buf)
{
	struct bt_hci_acl_hdr *hdr;
	uint16_t len, handle;
	uint8_t flags;

	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
	len = sys_le16_to_cpu(hdr->len);
	handle = sys_le16_to_cpu(hdr->handle);

	flags = bt_acl_flags(handle);
	handle = bt_acl_handle(handle);

	/* fragmentation not supported */
	__ASSERT_NO_MSG(flags == BT_ACL_START);

	LOG_DBG("ACL: conn %d len %d flags %d", handle, len, flags);
	LOG_HEXDUMP_DBG(buf->data, buf->len, "HCI ACL");

	handle_l2cap(buf);
}

static void recv(struct net_buf *buf)
{
	LOG_HEXDUMP_DBG(buf->data, buf->len, "HCI RX");

	uint8_t code = buf->data[0];

	if (bt_buf_get_type(buf) == BT_BUF_EVT) {
		switch (code) {
		case BT_HCI_EVT_CMD_COMPLETE:
		case BT_HCI_EVT_CMD_STATUS:
			handle_cmd_complete(buf);
			break;
		case BT_HCI_EVT_LE_META_EVENT:
			handle_meta_event(buf);
			break;
		case BT_HCI_EVT_DISCONN_COMPLETE:
			UNSET_FLAG(is_connected);
			break;
		case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
			handle_ncp(buf);
			break;
		default:
			LOG_ERR("unhandled msg %x", code);
			LOG_HEXDUMP_ERR(buf->data, buf->len, "HCI EVT");
		}

		/* handlers should take a ref if they want to access the buffer
		 * later
		 */
		net_buf_unref(buf);
		return;
	}

	if (bt_buf_get_type(buf) == BT_BUF_ACL_IN) {
		handle_acl(buf);
		net_buf_unref(buf);
		return;
	}

	LOG_ERR("HCI RX (not data or event)");
	net_buf_unref(buf);
}

static void send_cmd(uint16_t opcode, struct net_buf *cmd, struct net_buf **rsp)
{
	LOG_DBG("opcode %x", opcode);

	if (!cmd) {
		cmd = bt_hci_cmd_create(opcode, 0);
	}

	k_sem_take(&cmd_sem, K_FOREVER);
	__ASSERT_NO_MSG(active_opcode == 0xFFFF);

	active_opcode = opcode;

	LOG_HEXDUMP_DBG(cmd->data, cmd->len, "HCI TX");
	bt_send(cmd);

	/* Wait until the command completes */
	k_sem_take(&cmd_sem, K_FOREVER);
	k_sem_give(&cmd_sem);

	net_buf_unref(cmd);

	/* return response. it's okay if cmd_rsp gets overwritten, since the app
	 * gets the ref to the underlying buffer when this fn returns.
	 */
	if (rsp) {
		*rsp = cmd_rsp;
	} else {
		net_buf_unref(cmd_rsp);
		cmd_rsp = NULL;
	}
}

static K_THREAD_STACK_DEFINE(rx_thread_stack, 1024);
static struct k_thread rx_thread_data;

static void rx_thread(void *p1, void *p2, void *p3)
{
	LOG_DBG("start HCI rx");

	while (1) {
		struct net_buf *buf;

		/* Wait until a buffer is available */
		buf = net_buf_get(&rx_queue, K_FOREVER);
		recv(buf);
	}
}

static void le_read_buffer_size_complete(struct net_buf *rsp)
{
	struct bt_hci_rp_le_read_buffer_size *rp = (void *)rsp->data;

	LOG_DBG("status 0x%02x", rp->status);
	LOG_DBG("max len %d max num %d", rp->le_max_len, rp->le_max_num);

	k_sem_init(&acl_pkts, rp->le_max_num, rp->le_max_num);
	net_buf_unref(rsp);
}

static void read_max_data_len(uint16_t *tx_octets, uint16_t *tx_time)
{
	struct bt_hci_rp_le_read_max_data_len *rp;
	struct net_buf *rsp;

	send_cmd(BT_HCI_OP_LE_READ_MAX_DATA_LEN, NULL, &rsp);

	rp = (void *)rsp->data;
	*tx_octets = sys_le16_to_cpu(rp->max_tx_octets);
	*tx_time = sys_le16_to_cpu(rp->max_tx_time);
	net_buf_unref(rsp);
}

static void write_default_data_len(uint16_t tx_octets, uint16_t tx_time)
{
	struct bt_hci_cp_le_write_default_data_len *cp;
	struct net_buf *buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN, sizeof(*cp));

	__ASSERT_NO_MSG(buf);

	cp = net_buf_add(buf, sizeof(*cp));
	cp->max_tx_octets = sys_cpu_to_le16(tx_octets);
	cp->max_tx_time = sys_cpu_to_le16(tx_time);

	send_cmd(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN, buf, NULL);
}

static void set_data_len(void)
{
	uint16_t tx_octets, tx_time;

	read_max_data_len(&tx_octets, &tx_time);
	write_default_data_len(tx_octets, tx_time);
}

static void set_event_mask(uint16_t opcode)
{
	struct bt_hci_cp_set_event_mask *cp_mask;
	struct net_buf *buf;
	uint64_t mask = 0U;

	/* The two commands have the same length/params */
	buf = bt_hci_cmd_create(opcode, sizeof(*cp_mask));
	__ASSERT_NO_MSG(buf);

	/* Forward all events */
	cp_mask = net_buf_add(buf, sizeof(*cp_mask));
	mask = UINT64_MAX;
	sys_put_le64(mask, cp_mask->events);

	send_cmd(opcode, buf, NULL);
}

static void set_random_address(void)
{
	struct net_buf *buf;
	bt_addr_le_t addr = {BT_ADDR_LE_RANDOM, {{0x0A, 0x89, 0x67, 0x45, 0x23, 0xC1}}};

	LOG_DBG("%s", bt_addr_str(&addr.a));

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_RANDOM_ADDRESS, sizeof(addr.a));
	__ASSERT_NO_MSG(buf);

	net_buf_add_mem(buf, &addr.a, sizeof(addr.a));
	send_cmd(BT_HCI_OP_LE_SET_RANDOM_ADDRESS, buf, NULL);
}

void start_adv(uint16_t interval)
{
	struct bt_hci_cp_le_set_adv_param set_param;
	struct net_buf *buf;

	(void)memset(&set_param, 0, sizeof(set_param));

	set_param.min_interval = sys_cpu_to_le16(interval);
	set_param.max_interval = sys_cpu_to_le16(interval);
	set_param.channel_map = 0x07;
	set_param.filter_policy = BT_LE_ADV_FP_NO_FILTER;
	set_param.type = BT_HCI_ADV_IND;
	set_param.own_addr_type = 0x01; /* random */

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_PARAM, sizeof(set_param));
	__ASSERT_NO_MSG(buf);
	net_buf_add_mem(buf, &set_param, sizeof(set_param));

	send_cmd(BT_HCI_OP_LE_SET_ADV_PARAM, buf, NULL);

	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1);
	__ASSERT_NO_MSG(buf);

	net_buf_add_u8(buf, BT_HCI_LE_ADV_ENABLE);
	send_cmd(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL);
}

NET_BUF_POOL_DEFINE(acl_tx_pool, 5, BT_L2CAP_BUF_SIZE(200), 8, NULL);

struct net_buf *alloc_l2cap_pdu(void)
{
	struct net_buf *buf;
	uint16_t reserve;

	buf = net_buf_alloc(&acl_tx_pool, K_FOREVER);
	__ASSERT_NO_MSG(buf);

	reserve = sizeof(struct bt_l2cap_hdr);
	reserve += sizeof(struct bt_hci_acl_hdr) + BT_BUF_RESERVE;

	net_buf_reserve(buf, reserve);

	return buf;
}

static struct net_buf *l2cap_create_le_sig_pdu(uint8_t code, uint8_t ident, uint16_t len)
{
	struct bt_l2cap_sig_hdr *hdr;
	struct net_buf *buf;

	buf = alloc_l2cap_pdu();

	hdr = net_buf_add(buf, sizeof(*hdr));
	hdr->code = code;
	hdr->ident = ident;
	hdr->len = sys_cpu_to_le16(len);

	return buf;
}

static int send_acl(struct net_buf *buf)
{
	struct bt_hci_acl_hdr *hdr;
	uint8_t flags = BT_ACL_START_NO_FLUSH;

	hdr = net_buf_push(buf, sizeof(*hdr));
	hdr->handle = sys_cpu_to_le16(bt_acl_handle_pack(conn_handle, flags));
	hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr));

	bt_buf_set_type(buf, BT_BUF_ACL_OUT);

	k_sem_take(&acl_pkts, K_FOREVER);

	return bt_send(buf);
}

static void send_l2cap_packet(struct net_buf *buf, uint16_t cid)
{
	struct bt_l2cap_hdr *hdr;

	hdr = net_buf_push(buf, sizeof(*hdr));
	hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr));
	hdr->cid = sys_cpu_to_le16(cid);

	/* Always entire packets, no HCI fragmentation */
	__ASSERT_NO_MSG(buf->len <= CONFIG_BT_BUF_ACL_TX_SIZE);

	send_acl(buf);
}

static void open_l2cap(void)
{
	struct net_buf *buf;
	struct bt_l2cap_le_conn_req *req;

	buf = l2cap_create_le_sig_pdu(BT_L2CAP_LE_CONN_REQ, 1, sizeof(*req));

	req = net_buf_add(buf, sizeof(*req));
	req->psm = sys_cpu_to_le16(L2CAP_PSM);
	req->scid = sys_cpu_to_le16(L2CAP_CID);

	/* we don't intend on receiving anything. use the smallest allowed
	 * values and no initial credits.
	 */
	req->mtu = sys_cpu_to_le16(23);
	req->mps = sys_cpu_to_le16(23);
	req->credits = sys_cpu_to_le16(0);

	send_l2cap_packet(buf, BT_L2CAP_CID_LE_SIG);

	WAIT_FOR_FLAG(flag_l2cap_connected);
}

static void send_l2cap_sdu(uint8_t *data, uint16_t sdu_len, uint16_t mps)
{
	uint16_t pdu_len;

	/* have some fun with the packet size if not specified */
	bool shenanigans = !mps;
	int increment = -1;

	if (!mps) {
		/* need at least two bytes to fit the SDU length */
		mps = 2;
	}

	for (int i = 0; sdu_len; i++) {
		struct net_buf *buf = net_buf_alloc(&acl_tx_pool, K_FOREVER);

		__ASSERT_NO_MSG(buf);
		net_buf_reserve(buf, BT_L2CAP_SDU_CHAN_SEND_RESERVE);

		pdu_len = MIN(sdu_len, mps);

		if (i == 0) {
			/* add SDU len to first packet */
			net_buf_push_le16(buf, sdu_len);
			pdu_len -= BT_L2CAP_SDU_HDR_SIZE;
		}

		net_buf_add_mem(buf, data, pdu_len); /* add data */

		data = &data[pdu_len];
		sdu_len -= pdu_len;

		if (shenanigans) {
			if (mps == 1) {
				increment = 1;
			} else if (mps == 10) {
				increment = -1;
			}
			mps += increment;
		}

		LOG_INF("send PDU %d (%d bytes, remaining %d)", i, buf->len, sdu_len);
		LOG_HEXDUMP_DBG(buf->data, buf->len, "PDU");

		k_sem_take(&tx_credits, K_FOREVER);
		send_l2cap_packet(buf, 0x0040);
	}

	LOG_INF("SDU sent ok");
}

void test_procedure_0(void)
{
	bt_enable_raw(&rx_queue);

	/* Start the RX thread */
	k_thread_create(&rx_thread_data, rx_thread_stack,
			K_THREAD_STACK_SIZEOF(rx_thread_stack), rx_thread,
			NULL, NULL, NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
	k_thread_name_set(&rx_thread_data, "HCI RX");

	k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(0));

	/* Initialize controller */
	struct net_buf *rsp;

	send_cmd(BT_HCI_OP_RESET, NULL, NULL);
	send_cmd(BT_HCI_OP_LE_READ_BUFFER_SIZE, NULL, &rsp);
	le_read_buffer_size_complete(rsp);

	set_data_len();
	set_event_mask(BT_HCI_OP_SET_EVENT_MASK);
	set_event_mask(BT_HCI_OP_LE_SET_EVENT_MASK);
	set_random_address();

	/* Start advertising & wait for a connection */
	start_adv(60); /* Interval doesn't matter */
	WAIT_FOR_FLAG(is_connected);
	LOG_DBG("connected");

	/* We need this to be able to send whole L2CAP PDUs on-air. */
	WAIT_FOR_FLAG(flag_data_length_updated);

	/* Connect to the central's dynamic L2CAP server */
	open_l2cap();

	/* Prepare the data for sending */
	uint8_t data[L2CAP_SDU_LEN];

	for (int i = 0; i < ARRAY_SIZE(data); i++) {
		data[i] = (uint8_t)i;
	}

	/* Send the first SDU, lowering the PDU size for each subsequent PDU */
	send_l2cap_sdu(data, sizeof(data), 0);

	/* Send the second SDU respecting peer's MPS */
	send_l2cap_sdu(data, sizeof(data), peer_mps);

	WAIT_FOR_FLAG_UNSET(is_connected);
	LOG_DBG("disconnected");

	PASS("Tester done\n");
}

void test_tick(bs_time_t HW_device_time)
{
	bs_trace_debug_time(0, "Simulation ends now.\n");
	if (bst_result != Passed) {
		bst_result = Failed;
		bs_trace_error("Test did not pass before simulation ended.\n");
	}
}

void test_init(void)
{
	bst_ticker_set_next_tick_absolute(TEST_TIMEOUT_SIMULATED);
	bst_result = In_progress;
}

static const struct bst_test_instance test_to_add[] = {
	{
		.test_id = "test_0",
		.test_pre_init_f = test_init,
		.test_tick_f = test_tick,
		.test_main_f = test_procedure_0,
	},
	BSTEST_END_MARKER,
};

static struct bst_test_list *install(struct bst_test_list *tests)
{
	return bst_add_tests(tests, test_to_add);
};

bst_test_install_t test_installers[] = {install, NULL};


int main(void)
{
	bst_main();

	return 0;
}
