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

#include <zephyr/types.h>

#include <zephyr/bluetooth/hci.h>

#include "hal/cpu_vendor_hal.h"
#include "hal/ccm.h"

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

#include "pdu.h"
#include "ll.h"
#include "ll_feat.h"
#include "ll_settings.h"
#include "lll.h"
#include "lll_vendor.h"
#include "lll/lll_adv_types.h"
#include "lll_adv.h"
#include "lll/lll_adv_pdu.h"
#include "lll_scan.h"
#include "lll_sync.h"
#include "lll/lll_df_types.h"
#include "lll_conn.h"

#include "ull_conn_internal.h"

#define EVENT_DONE_MAX 3
/* Backing storage for elements in mfifo_done */
static struct {
	void *free;
	uint8_t pool[sizeof(struct node_rx_event_done) * EVENT_DONE_MAX];
} mem_done;

static struct {
	void *free;
	uint8_t pool[sizeof(memq_link_t) * EVENT_DONE_MAX];
} mem_link_done;

#if defined(CONFIG_BT_CTLR_PHY) && defined(CONFIG_BT_CTLR_DATA_LENGTH)
#define LL_PDU_RX_CNT (3 + 128)
#else
#define LL_PDU_RX_CNT (2 + 128)
#endif

#define PDU_RX_CNT (CONFIG_BT_CTLR_RX_BUFFERS + 3)
#define RX_CNT (PDU_RX_CNT + LL_PDU_RX_CNT)

static MFIFO_DEFINE(pdu_rx_free, sizeof(void *), PDU_RX_CNT);

#if defined(CONFIG_BT_RX_USER_PDU_LEN)
#define PDU_RX_USER_PDU_OCTETS_MAX (CONFIG_BT_RX_USER_PDU_LEN)
#else
#define PDU_RX_USER_PDU_OCTETS_MAX 0
#endif
#define NODE_RX_HEADER_SIZE (offsetof(struct node_rx_pdu, pdu))
#define NODE_RX_STRUCT_OVERHEAD (NODE_RX_HEADER_SIZE)

#define PDU_ADV_SIZE  MAX(PDU_AC_LL_SIZE_MAX, \
			  (PDU_AC_LL_HEADER_SIZE + LL_EXT_OCTETS_RX_MAX))

#define PDU_DATA_SIZE (PDU_DC_LL_HEADER_SIZE + LL_LENGTH_OCTETS_RX_MAX)

#define PDU_RX_NODE_POOL_ELEMENT_SIZE                                                              \
	MROUND(NODE_RX_STRUCT_OVERHEAD +                                                           \
	       MAX(MAX(PDU_ADV_SIZE, PDU_DATA_SIZE), PDU_RX_USER_PDU_OCTETS_MAX))

/*
 * just a big number
 */
#define PDU_RX_POOL_SIZE 16384

static struct {
	void *free;
	uint8_t pool[PDU_RX_POOL_SIZE];
} mem_pdu_rx;

/*
 * just a big number
 */
#define LINK_RX_POOL_SIZE 16384
static struct {
	uint8_t quota_pdu; /* Number of un-utilized buffers */

	void *free;
	uint8_t pool[LINK_RX_POOL_SIZE];
} mem_link_rx;

static MEMQ_DECLARE(ull_rx);
static MEMQ_DECLARE(ll_rx);

#if defined(CONFIG_BT_CONN)
static MFIFO_DEFINE(ll_pdu_rx_free, sizeof(void *), LL_PDU_RX_CNT);
#endif /* CONFIG_BT_CONN */

#ifdef ZTEST_UNITTEST
extern sys_slist_t ut_rx_q;
#else
sys_slist_t ut_rx_q;
#endif

static inline int init_reset(void);
static inline void rx_alloc(uint8_t max);
static inline void ll_rx_link_inc_quota(int8_t delta);

void ll_reset(void)
{
	MFIFO_INIT(ll_pdu_rx_free);
	init_reset();
}

void ll_rx_mem_release(void **node_rx)
{
	struct node_rx_hdr *rx;

	rx = *node_rx;
	while (rx) {
		struct node_rx_hdr *rx_free;

		rx_free = rx;
		rx = rx->next;

		switch (rx_free->type) {
		case NODE_RX_TYPE_DC_PDU:
			ll_rx_link_inc_quota(1);
			mem_release(rx_free, &mem_pdu_rx.free);
			break;
		default:
			__ASSERT(0, "Tried to release unknown rx node type");
			break;
		}
	}

	*node_rx = rx;

	rx_alloc(UINT8_MAX);
}

static inline void ll_rx_link_inc_quota(int8_t delta)
{
	mem_link_rx.quota_pdu += delta;
}

void *ll_rx_link_alloc(void)
{
	return mem_acquire(&mem_link_rx.free);
}

void ll_rx_link_release(void *link)
{
	mem_release(link, &mem_link_rx.free);
}

void *ll_rx_alloc(void)
{
	return mem_acquire(&mem_pdu_rx.free);
}

void ll_rx_release(void *node_rx)
{
	mem_release(node_rx, &mem_pdu_rx.free);
}

void ll_rx_put(memq_link_t *link, void *rx)
{
	sys_slist_append(&ut_rx_q, (sys_snode_t *)rx);
}

void ll_rx_sched(void)
{
}

void *ll_pdu_rx_alloc_peek(uint8_t count)
{
	if (count > MFIFO_AVAIL_COUNT_GET(ll_pdu_rx_free)) {
		return NULL;
	}

	return MFIFO_DEQUEUE_PEEK(ll_pdu_rx_free);
}

void *ll_pdu_rx_alloc(void)
{
	return MFIFO_DEQUEUE(ll_pdu_rx_free);
}

void ll_tx_ack_put(uint16_t handle, struct node_tx *node)
{
}

void ull_ticker_status_give(uint32_t status, void *param)
{
}

uint32_t ull_ticker_status_take(uint32_t ret, uint32_t volatile *ret_cb)
{
	return *ret_cb;
}

void *ull_disable_mark(void *param)
{
	return NULL;
}

void *ull_disable_unmark(void *param)
{
	return NULL;
}

void *ull_disable_mark_get(void)
{
	return NULL;
}

int ull_ticker_stop_with_mark(uint8_t ticker_handle, void *param, void *lll_disable)
{
	return 0;
}

void *ull_update_mark(void *param)
{
	return NULL;
}

void *ull_update_unmark(void *param)
{
	return NULL;
}

void *ull_update_mark_get(void)
{
	return NULL;
}

int ull_disable(void *lll)
{
	return 0;
}

void ull_rx_put(memq_link_t *link, void *rx)
{
}

void ull_rx_sched(void)
{
}

/* Forward declaration */
struct node_rx_event_done;
void ull_drift_ticks_get(struct node_rx_event_done *done, uint32_t *ticks_drift_plus,
			 uint32_t *ticks_drift_minus)
{
}

static inline int init_reset(void)
{
	memq_link_t *link;

	/* Initialize done pool. */
	mem_init(mem_done.pool, sizeof(struct node_rx_event_done), EVENT_DONE_MAX, &mem_done.free);

	/* Initialize done link pool. */
	mem_init(mem_link_done.pool, sizeof(memq_link_t), EVENT_DONE_MAX, &mem_link_done.free);

	/* Initialize rx pool. */
	mem_init(mem_pdu_rx.pool, (PDU_RX_NODE_POOL_ELEMENT_SIZE),
		 sizeof(mem_pdu_rx.pool) / (PDU_RX_NODE_POOL_ELEMENT_SIZE), &mem_pdu_rx.free);

	/* Initialize rx link pool. */
	mem_init(mem_link_rx.pool, sizeof(memq_link_t),
		 sizeof(mem_link_rx.pool) / sizeof(memq_link_t), &mem_link_rx.free);

	/* Acquire a link to initialize ull rx memq */
	link = mem_acquire(&mem_link_rx.free);

	/* Initialize ull rx memq */
	MEMQ_INIT(ull_rx, link);

	/* Acquire a link to initialize ll rx memq */
	link = mem_acquire(&mem_link_rx.free);

	/* Initialize ll rx memq */
	MEMQ_INIT(ll_rx, link);

	/* Allocate rx free buffers */
	mem_link_rx.quota_pdu = RX_CNT;
	rx_alloc(UINT8_MAX);

#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
	/* Reset CPR mutex */
	cpr_active_reset();
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */

	return 0;
}

static inline void rx_alloc(uint8_t max)
{
	uint8_t idx;

#if defined(CONFIG_BT_CONN)
	while (mem_link_rx.quota_pdu && MFIFO_ENQUEUE_IDX_GET(ll_pdu_rx_free, &idx)) {
		memq_link_t *link;
		struct node_rx_hdr *rx;

		link = mem_acquire(&mem_link_rx.free);
		if (!link) {
			break;
		}

		rx = mem_acquire(&mem_pdu_rx.free);
		if (!rx) {
			mem_release(link, &mem_link_rx.free);
			break;
		}

		link->mem = NULL;
		rx->link = link;

		MFIFO_BY_IDX_ENQUEUE(ll_pdu_rx_free, idx, rx);

		ll_rx_link_inc_quota(-1);
	}
#endif /* CONFIG_BT_CONN */

	if (max > mem_link_rx.quota_pdu) {
		max = mem_link_rx.quota_pdu;
	}

	while ((max--) && MFIFO_ENQUEUE_IDX_GET(pdu_rx_free, &idx)) {
		memq_link_t *link;
		struct node_rx_hdr *rx;

		link = mem_acquire(&mem_link_rx.free);
		if (!link) {
			break;
		}

		rx = mem_acquire(&mem_pdu_rx.free);
		if (!rx) {
			mem_release(link, &mem_link_rx.free);
			break;
		}

		rx->link = link;

		MFIFO_BY_IDX_ENQUEUE(pdu_rx_free, idx, rx);

		ll_rx_link_inc_quota(-1);
	}
}
