/*
 * Copyright (c) 2016 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_ieee802154_fake_driver, LOG_LEVEL_DBG);

#include <zephyr/kernel.h>

#include <zephyr/net/net_core.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_pkt.h>

/** FAKE ieee802.15.4 driver **/
#include <zephyr/net/ieee802154_radio.h>

#include "net_private.h"
#include <ieee802154_frame.h>

struct net_pkt *current_pkt;
K_SEM_DEFINE(driver_lock, 0, UINT_MAX);

uint8_t mock_ext_addr_be[8] = {0x00, 0x12, 0x4b, 0x00, 0x00, 0x9e, 0xa3, 0xc2};

static enum ieee802154_hw_caps fake_get_capabilities(const struct device *dev)
{
	return IEEE802154_HW_FCS;
}

static int fake_cca(const struct device *dev)
{
	return 0;
}

static int fake_set_channel(const struct device *dev, uint16_t channel)
{
	NET_INFO("Channel %u\n", channel);

	return 0;
}

static int fake_set_txpower(const struct device *dev, int16_t dbm)
{
	NET_INFO("TX power %d dbm\n", dbm);

	return 0;
}

static inline void insert_frag(struct net_pkt *pkt, struct net_buf *frag)
{
	struct net_buf *new_frag;

	new_frag = net_pkt_get_frag(pkt, frag->len, K_SECONDS(1));
	if (!new_frag) {
		return;
	}

	memcpy(new_frag->data, frag->data, frag->len);
	net_buf_add(new_frag, frag->len);

	net_pkt_frag_add(current_pkt, new_frag);
}

static int fake_tx(const struct device *dev,
		   enum ieee802154_tx_mode mode,
		   struct net_pkt *pkt,
		   struct net_buf *frag)
{
	NET_INFO("Sending packet %p - length %zu\n",
		 pkt, net_pkt_get_len(pkt));

	if (!current_pkt) {
		return 0;
	}

	insert_frag(pkt, frag);

	if (ieee802154_is_ar_flag_set(frag)) {
		struct net_if *iface = net_if_lookup_by_dev(dev);
		struct ieee802154_context *ctx = net_if_l2_data(iface);

		struct net_pkt *ack_pkt;

		ack_pkt = net_pkt_rx_alloc_with_buffer(iface, IEEE802154_ACK_PKT_LENGTH, AF_UNSPEC,
						       0, K_FOREVER);
		if (!ack_pkt) {
			NET_ERR("*** Could not allocate ack pkt.\n");
			return -ENOMEM;
		}

		if (!ieee802154_create_ack_frame(iface, ack_pkt, ctx->ack_seq)) {
			NET_ERR("*** Could not create ack frame.\n");
			net_pkt_unref(ack_pkt);
			return -EFAULT;
		}

		ieee802154_handle_ack(iface, ack_pkt);
		net_pkt_unref(ack_pkt);
	}

	k_sem_give(&driver_lock);

	return 0;
}

static int fake_start(const struct device *dev)
{
	NET_INFO("FAKE ieee802154 driver started\n");

	return 0;
}

static int fake_stop(const struct device *dev)
{
	NET_INFO("FAKE ieee802154 driver stopped\n");

	return 0;
}

/* driver-allocated attribute memory - constant across all driver instances */
IEEE802154_DEFINE_PHY_SUPPORTED_CHANNELS(drv_attr, 11, 26);

/* API implementation: attr_get */
static int fake_attr_get(const struct device *dev, enum ieee802154_attr attr,
			 struct ieee802154_attr_value *value)
{
	ARG_UNUSED(dev);

	return ieee802154_attr_get_channel_page_and_range(
		attr, IEEE802154_ATTR_PHY_CHANNEL_PAGE_ZERO_OQPSK_2450_BPSK_868_915,
		&drv_attr.phy_supported_channels, value);
}

static void fake_iface_init(struct net_if *iface)
{
	struct ieee802154_context *ctx = net_if_l2_data(iface);

	net_if_set_link_addr(iface, mock_ext_addr_be, 8, NET_LINK_IEEE802154);

	ieee802154_init(iface);

	ctx->pan_id = IEEE802154_PAN_ID_NOT_ASSOCIATED;
	ctx->short_addr = IEEE802154_SHORT_ADDRESS_NOT_ASSOCIATED;
	ctx->channel = 26U;
	ctx->sequence = 62U;

	NET_INFO("FAKE ieee802154 iface initialized\n");
}

static int fake_init(const struct device *dev)
{
	fake_stop(dev);

	return 0;
}

static struct ieee802154_radio_api fake_radio_api = {
	.iface_api.init	= fake_iface_init,

	.get_capabilities	= fake_get_capabilities,
	.cca			= fake_cca,
	.set_channel		= fake_set_channel,
	.set_txpower		= fake_set_txpower,
	.start			= fake_start,
	.stop			= fake_stop,
	.tx			= fake_tx,
	.attr_get		= fake_attr_get,
};

NET_DEVICE_INIT(fake, "fake_ieee802154",
		fake_init, NULL, NULL, NULL,
		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
		&fake_radio_api, IEEE802154_L2,
		NET_L2_GET_CTX_TYPE(IEEE802154_L2), IEEE802154_MTU);
