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

#include <zephyr/init.h>
#include <zephyr/sys/byteorder.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/drivers/bluetooth/hci_driver.h>

#include <zephyr/device.h>
#include <zephyr/ipc/ipc_service.h>

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_DRIVER)
#define LOG_MODULE_NAME bt_hci_driver
#include "common/log.h"

#define RPMSG_CMD 0x01
#define RPMSG_ACL 0x02
#define RPMSG_SCO 0x03
#define RPMSG_EVT 0x04
#define RPMSG_ISO 0x05

#define IPC_BOUND_TIMEOUT_IN_MS K_MSEC(1000)

static struct ipc_ept hci_ept;
static K_SEM_DEFINE(ipc_bound_sem, 0, 1);

static bool is_hci_event_discardable(const uint8_t *evt_data)
{
	uint8_t evt_type = evt_data[0];

	switch (evt_type) {
#if defined(CONFIG_BT_BREDR)
	case BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI:
	case BT_HCI_EVT_EXTENDED_INQUIRY_RESULT:
		return true;
#endif
	case BT_HCI_EVT_LE_META_EVENT: {
		uint8_t subevt_type = evt_data[sizeof(struct bt_hci_evt_hdr)];

		switch (subevt_type) {
		case BT_HCI_EVT_LE_ADVERTISING_REPORT:
			return true;
		default:
			return false;
		}
	}
	default:
		return false;
	}
}

static struct net_buf *bt_rpmsg_evt_recv(const uint8_t *data, size_t remaining)
{
	bool discardable;
	struct bt_hci_evt_hdr hdr;
	struct net_buf *buf;
	size_t buf_tailroom;

	if (remaining < sizeof(hdr)) {
		BT_ERR("Not enough data for event header");
		return NULL;
	}

	discardable = is_hci_event_discardable(data);

	memcpy((void *)&hdr, data, sizeof(hdr));
	data += sizeof(hdr);
	remaining -= sizeof(hdr);

	if (remaining != hdr.len) {
		BT_ERR("Event payload length is not correct");
		return NULL;
	}
	BT_DBG("len %u", hdr.len);

	do {
		buf = bt_buf_get_evt(hdr.evt, discardable, discardable ? K_NO_WAIT : K_SECONDS(10));
		if (!buf) {
			if (discardable) {
				BT_DBG("Discardable buffer pool full, ignoring event");
				return buf;
			}
			BT_WARN("Couldn't allocate a buffer after waiting 10 seconds.");
		}
	} while (!buf);

	net_buf_add_mem(buf, &hdr, sizeof(hdr));

	buf_tailroom = net_buf_tailroom(buf);
	if (buf_tailroom < remaining) {
		BT_ERR("Not enough space in buffer %zu/%zu",
		       remaining, buf_tailroom);
		net_buf_unref(buf);
		return NULL;
	}

	net_buf_add_mem(buf, data, remaining);

	return buf;
}

static struct net_buf *bt_rpmsg_acl_recv(const uint8_t *data, size_t remaining)
{
	struct bt_hci_acl_hdr hdr;
	struct net_buf *buf;
	size_t buf_tailroom;

	if (remaining < sizeof(hdr)) {
		BT_ERR("Not enough data for ACL header");
		return NULL;
	}

	buf = bt_buf_get_rx(BT_BUF_ACL_IN, K_NO_WAIT);
	if (buf) {
		memcpy((void *)&hdr, data, sizeof(hdr));
		data += sizeof(hdr);
		remaining -= sizeof(hdr);

		net_buf_add_mem(buf, &hdr, sizeof(hdr));
	} else {
		BT_ERR("No available ACL buffers!");
		return NULL;
	}

	if (remaining != sys_le16_to_cpu(hdr.len)) {
		BT_ERR("ACL payload length is not correct");
		net_buf_unref(buf);
		return NULL;
	}

	buf_tailroom = net_buf_tailroom(buf);
	if (buf_tailroom < remaining) {
		BT_ERR("Not enough space in buffer %zu/%zu",
		       remaining, buf_tailroom);
		net_buf_unref(buf);
		return NULL;
	}

	BT_DBG("len %u", remaining);
	net_buf_add_mem(buf, data, remaining);

	return buf;
}

static struct net_buf *bt_rpmsg_iso_recv(const uint8_t *data, size_t remaining)
{
	struct bt_hci_iso_hdr hdr;
	struct net_buf *buf;
	size_t buf_tailroom;

	if (remaining < sizeof(hdr)) {
		BT_ERR("Not enough data for ISO header");
		return NULL;
	}

	buf = bt_buf_get_rx(BT_BUF_ISO_IN, K_NO_WAIT);
	if (buf) {
		memcpy((void *)&hdr, data, sizeof(hdr));
		data += sizeof(hdr);
		remaining -= sizeof(hdr);

		net_buf_add_mem(buf, &hdr, sizeof(hdr));
	} else {
		BT_ERR("No available ISO buffers!");
		return NULL;
	}

	if (remaining != bt_iso_hdr_len(sys_le16_to_cpu(hdr.len))) {
		BT_ERR("ISO payload length is not correct");
		net_buf_unref(buf);
		return NULL;
	}

	buf_tailroom = net_buf_tailroom(buf);
	if (buf_tailroom < remaining) {
		BT_ERR("Not enough space in buffer %zu/%zu",
		       remaining, buf_tailroom);
		net_buf_unref(buf);
		return NULL;
	}

	BT_DBG("len %zu", remaining);
	net_buf_add_mem(buf, data, remaining);

	return buf;
}

static void bt_rpmsg_rx(const uint8_t *data, size_t len)
{
	uint8_t pkt_indicator;
	struct net_buf *buf = NULL;
	size_t remaining = len;

	BT_HEXDUMP_DBG(data, len, "RPMsg data:");

	pkt_indicator = *data++;
	remaining -= sizeof(pkt_indicator);

	switch (pkt_indicator) {
	case RPMSG_EVT:
		buf = bt_rpmsg_evt_recv(data, remaining);
		break;

	case RPMSG_ACL:
		buf = bt_rpmsg_acl_recv(data, remaining);
		break;

	case RPMSG_ISO:
		buf = bt_rpmsg_iso_recv(data, remaining);
		break;

	default:
		BT_ERR("Unknown HCI type %u", pkt_indicator);
		return;
	}

	if (buf) {
		BT_DBG("Calling bt_recv(%p)", buf);

		bt_recv(buf);

		BT_HEXDUMP_DBG(buf->data, buf->len, "RX buf payload:");
	}
}

static int bt_rpmsg_send(struct net_buf *buf)
{
	int err;
	uint8_t pkt_indicator;

	BT_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);

	switch (bt_buf_get_type(buf)) {
	case BT_BUF_ACL_OUT:
		pkt_indicator = RPMSG_ACL;
		break;
	case BT_BUF_CMD:
		pkt_indicator = RPMSG_CMD;
		break;
	case BT_BUF_ISO_OUT:
		pkt_indicator = RPMSG_ISO;
		break;
	default:
		BT_ERR("Unknown type %u", bt_buf_get_type(buf));
		goto done;
	}
	net_buf_push_u8(buf, pkt_indicator);

	BT_HEXDUMP_DBG(buf->data, buf->len, "Final HCI buffer:");
	err = ipc_service_send(&hci_ept, buf->data, buf->len);
	if (err < 0) {
		BT_ERR("Failed to send (err %d)", err);
	}

done:
	net_buf_unref(buf);
	return 0;
}

static void hci_ept_bound(void *priv)
{
	k_sem_give(&ipc_bound_sem);
}

static void hci_ept_recv(const void *data, size_t len, void *priv)
{
	bt_rpmsg_rx(data, len);
}

static struct ipc_ept_cfg hci_ept_cfg = {
	.name = "nrf_bt_hci",
	.cb = {
		.bound    = hci_ept_bound,
		.received = hci_ept_recv,
	},
};

static int bt_rpmsg_open(void)
{
	int err;
	const struct device *hci_ipc_instance =
		DEVICE_DT_GET(DT_CHOSEN(zephyr_bt_hci_rpmsg_ipc));

	BT_DBG("");

	err = ipc_service_open_instance(hci_ipc_instance);
	if (err && (err != -EALREADY)) {
		BT_ERR("IPC service instance initialization failed: %d\n", err);
		return err;
	}

	err = ipc_service_register_endpoint(hci_ipc_instance, &hci_ept, &hci_ept_cfg);
	if (err) {
		BT_ERR("Registering endpoint failed with %d", err);
		return err;
	}

	err = k_sem_take(&ipc_bound_sem, IPC_BOUND_TIMEOUT_IN_MS);
	if (err) {
		BT_ERR("Endpoint binding failed with %d", err);
		return err;
	}

	return 0;
}

static const struct bt_hci_driver drv = {
	.name		= "RPMsg",
	.open		= bt_rpmsg_open,
	.send		= bt_rpmsg_send,
	.bus		= BT_HCI_DRIVER_BUS_IPM,
#if defined(CONFIG_BT_DRIVER_QUIRK_NO_AUTO_DLE)
	.quirks         = BT_QUIRK_NO_AUTO_DLE,
#endif
};

static int bt_rpmsg_init(const struct device *unused)
{
	ARG_UNUSED(unused);

	int err;

	err = bt_hci_driver_register(&drv);
	if (err < 0) {
		BT_ERR("Failed to register BT HIC driver (err %d)", err);
	}

	return err;
}

SYS_INIT(bt_rpmsg_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
