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

/** @file
 * @brief IEEE 802.15.4 shell module
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_ieee802154_shell, CONFIG_NET_L2_IEEE802154_LOG_LEVEL);

#include <zephyr/kernel.h>
#include <stdio.h>
#include <stdlib.h>
#include <zephyr/shell/shell.h>
#include <zephyr/sys/printk.h>

#include <zephyr/net/net_if.h>
#include <zephyr/net/ieee802154_mgmt.h>

#include "ieee802154_frame.h"

#define EXT_ADDR_STR_SIZE sizeof("xx:xx:xx:xx:xx:xx:xx:xx")
#define EXT_ADDR_STR_LEN (EXT_ADDR_STR_SIZE - 1U)

struct ieee802154_req_params params;
static struct net_mgmt_event_callback scan_cb;
static const struct shell *cb_shell;

static int cmd_ieee802154_ack(const struct shell *sh,
			      size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();

	ARG_UNUSED(argc);

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	if (!strcmp(argv[1], "set") || !strcmp(argv[1], "1")) {
		net_mgmt(NET_REQUEST_IEEE802154_SET_ACK, iface, NULL, 0);
		shell_fprintf(sh, SHELL_NORMAL,
			      "ACK flag set on outgoing packets\n");

		return 0;
	}

	if (!strcmp(argv[1], "unset") || !strcmp(argv[1], "0")) {
		net_mgmt(NET_REQUEST_IEEE802154_UNSET_ACK, iface, NULL, 0);
		shell_fprintf(sh, SHELL_NORMAL,
			      "ACK flag unset on outgoing packets\n");

		return 0;
	}

	return 0;
}

/**
 * Parse a string representing an extended address in ASCII HEX
 * format into a big endian binary representation of the address.
 *
 * @param addr Extended address as a string.
 * @param ext_addr Extended address in big endian byte ordering.
 *
 * @return 0 on success, negative error code otherwise
 */
static inline int parse_extended_address(char *addr, uint8_t *ext_addr)
{
	return net_bytes_from_str(ext_addr, IEEE802154_EXT_ADDR_LENGTH, addr);
}

static int cmd_ieee802154_associate(const struct shell *sh,
				    size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	char ext_addr[EXT_ADDR_STR_SIZE];

	if (argc < 3) {
		shell_help(sh);
		return -ENOEXEC;
	}

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	if (strlen(argv[2]) > EXT_ADDR_STR_LEN) {
		shell_fprintf(sh, SHELL_INFO, "Address too long\n");
		return -ENOEXEC;
	}

	params = (struct ieee802154_req_params){0};
	params.pan_id = atoi(argv[1]);
	strncpy(ext_addr, argv[2], sizeof(ext_addr));

	if (strlen(ext_addr) == EXT_ADDR_STR_LEN) {
		if (parse_extended_address(ext_addr, params.addr) < 0) {
			shell_fprintf(sh, SHELL_INFO,
				      "Failed to parse extended address\n");
			return -ENOEXEC;
		}
		params.len = IEEE802154_EXT_ADDR_LENGTH;
	} else {
		params.short_addr = (uint16_t) atoi(ext_addr);
		params.len = IEEE802154_SHORT_ADDR_LENGTH;
	}

	if (net_mgmt(NET_REQUEST_IEEE802154_ASSOCIATE, iface,
		     &params, sizeof(struct ieee802154_req_params))) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not associate to %s on PAN ID %u\n",
			      argv[2], params.pan_id);

		return -ENOEXEC;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "Associated to PAN ID %u\n", params.pan_id);
	}

	return 0;
}

static int cmd_ieee802154_disassociate(const struct shell *sh,
				       size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	int ret;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	ret = net_mgmt(NET_REQUEST_IEEE802154_DISASSOCIATE, iface, NULL, 0);
	if (ret == -EALREADY) {
		shell_fprintf(sh, SHELL_INFO,
			      "Interface is not associated\n");

		return -ENOEXEC;
	} else if (ret) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not disassociate? (status: %i)\n", ret);

		return -ENOEXEC;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "Interface is now disassociated\n");
	}

	return 0;
}

static inline uint32_t parse_channel_set(char *str_set)
{
	uint32_t channel_set = 0U;
	char *p, *n;

	p = str_set;

	do {
		uint32_t chan;

		n = strchr(p, ':');
		if (n) {
			*n = '\0';
		}

		chan = atoi(p);
		if (chan > 0 && chan < 32) {
			channel_set |= BIT(chan - 1);
		}

		p = n ? n + 1 : n;
	} while (n);

	return channel_set;
}

static inline char *print_coordinator_address(char *buf, int buf_len)
{
	if (params.len == IEEE802154_EXT_ADDR_LENGTH) {
		int i, pos = 0;

		pos += snprintk(buf + pos, buf_len - pos, "(extended) ");

		for (i = 0; i < IEEE802154_EXT_ADDR_LENGTH; i++) {
			pos += snprintk(buf + pos, buf_len - pos,
					"%02X:", params.addr[i]);
		}

		buf[pos - 1] = '\0';
	} else {
		snprintk(buf, buf_len, "(short) %u", params.short_addr);
	}

	return buf;
}

static void scan_result_cb(struct net_mgmt_event_callback *cb,
			   uint32_t mgmt_event, struct net_if *iface)
{
	char buf[64];

	shell_fprintf(cb_shell, SHELL_NORMAL,
		      "\nChannel: %u\tPAN ID: %u\tCoordinator Address: %s\t "
		      "LQI: %u\n", params.channel, params.pan_id,
		      print_coordinator_address(buf, sizeof(buf)), params.lqi);
}

static int cmd_ieee802154_scan(const struct shell *sh,
			       size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	uint32_t scan_type;
	int ret = 0;

	if (argc < 3) {
		shell_help(sh);
		return -ENOEXEC;
	}

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	params = (struct ieee802154_req_params){0};

	net_mgmt_init_event_callback(&scan_cb, scan_result_cb,
				     NET_EVENT_IEEE802154_SCAN_RESULT);
	net_mgmt_add_event_callback(&scan_cb);

	if (!strcmp(argv[1], "active")) {
		scan_type = NET_REQUEST_IEEE802154_ACTIVE_SCAN;
	} else if (!strcmp(argv[1], "passive")) {
		scan_type = NET_REQUEST_IEEE802154_PASSIVE_SCAN;
	} else {
		ret = -ENOEXEC;
		goto release_event_cb;
	}

	if (!strcmp(argv[2], "all")) {
		params.channel_set = IEEE802154_ALL_CHANNELS;
	} else {
		params.channel_set = parse_channel_set(argv[2]);
	}

	if (!params.channel_set) {
		ret = -ENOEXEC;
		goto release_event_cb;
	}

	params.duration = atoi(argv[3]);

	shell_fprintf(sh, SHELL_NORMAL,
		      "%s Scanning (channel set: 0x%08x, duration %u ms)...\n",
		      scan_type == NET_REQUEST_IEEE802154_ACTIVE_SCAN ?
		      "Active" : "Passive", params.channel_set,
		      params.duration);

	cb_shell = sh;

	if (scan_type == NET_REQUEST_IEEE802154_ACTIVE_SCAN) {
		ret = net_mgmt(NET_REQUEST_IEEE802154_ACTIVE_SCAN, iface,
			       &params, sizeof(struct ieee802154_req_params));
	} else {
		ret = net_mgmt(NET_REQUEST_IEEE802154_PASSIVE_SCAN, iface,
			       &params, sizeof(struct ieee802154_req_params));
	}

	if (ret) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not raise a scan (status: %i)\n", ret);

		ret = -ENOEXEC;
		goto release_event_cb;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "Done\n");
	}

release_event_cb:
	net_mgmt_del_event_callback(&scan_cb);
	return ret;
}

static int cmd_ieee802154_set_chan(const struct shell *sh,
				   size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	uint16_t channel;

	if (argc < 2) {
		shell_help(sh);
		return -ENOEXEC;
	}

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	channel = (uint16_t)atoi(argv[1]);

	if (net_mgmt(NET_REQUEST_IEEE802154_SET_CHANNEL, iface,
		     &channel, sizeof(uint16_t))) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not set channel %u\n", channel);

		return -ENOEXEC;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "Channel %u set\n", channel);
	}

	return 0;
}

static int cmd_ieee802154_get_chan(const struct shell *sh,
				   size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	uint16_t channel;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	if (net_mgmt(NET_REQUEST_IEEE802154_GET_CHANNEL, iface,
		     &channel, sizeof(uint16_t))) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not get channel\n");

		return -ENOEXEC;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "Channel %u\n", channel);
	}

	return 0;
}

static int cmd_ieee802154_set_pan_id(const struct shell *sh,
				     size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	uint16_t pan_id;

	ARG_UNUSED(argc);

	if (argc < 2) {
		shell_help(sh);
		return -ENOEXEC;
	}

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	pan_id = (uint16_t)atoi(argv[1]);

	if (net_mgmt(NET_REQUEST_IEEE802154_SET_PAN_ID, iface,
		     &pan_id, sizeof(uint16_t))) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not set PAN ID %u\n", pan_id);

		return -ENOEXEC;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "PAN ID %u set\n", pan_id);
	}

	return 0;
}

static int cmd_ieee802154_get_pan_id(const struct shell *sh,
				     size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	uint16_t pan_id;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	if (net_mgmt(NET_REQUEST_IEEE802154_GET_PAN_ID, iface,
		     &pan_id, sizeof(uint16_t))) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not get PAN ID\n");

		return -ENOEXEC;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "PAN ID %u (0x%x)\n", pan_id, pan_id);
	}

	return 0;
}

static int cmd_ieee802154_set_ext_addr(const struct shell *sh,
				       size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	uint8_t addr[IEEE802154_EXT_ADDR_LENGTH]; /* in big endian */

	if (argc < 2) {
		shell_help(sh);
		return -ENOEXEC;
	}

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	if (strlen(argv[1]) != EXT_ADDR_STR_LEN) {
		shell_fprintf(sh, SHELL_INFO,
			      "%zd characters needed\n", EXT_ADDR_STR_LEN);
		return -ENOEXEC;
	}

	if (parse_extended_address(argv[1], addr) < 0) {
		shell_fprintf(sh, SHELL_INFO,
			      "Failed to parse extended address\n");
		return -ENOEXEC;
	}

	if (net_mgmt(NET_REQUEST_IEEE802154_SET_EXT_ADDR, iface,
		     addr, IEEE802154_EXT_ADDR_LENGTH)) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not set extended address\n");

		return -ENOEXEC;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "Extended address set\n");
	}

	return 0;
}

static int cmd_ieee802154_get_ext_addr(const struct shell *sh,
				       size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	uint8_t addr[IEEE802154_EXT_ADDR_LENGTH]; /* in big endian */

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	if (net_mgmt(NET_REQUEST_IEEE802154_GET_EXT_ADDR, iface,
		     addr, IEEE802154_EXT_ADDR_LENGTH)) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not get extended address\n");
		return -ENOEXEC;
	} else {
		static char ext_addr[EXT_ADDR_STR_SIZE];
		int i, pos = 0;

		for (i = 0; i < IEEE802154_EXT_ADDR_LENGTH; i++) {
			pos += snprintk(ext_addr + pos,
					EXT_ADDR_STR_SIZE - pos,
					"%02X:", addr[i]);
		}

		ext_addr[EXT_ADDR_STR_SIZE - 1] = '\0';

		shell_fprintf(sh, SHELL_NORMAL,
			      "Extended address: %s\n", ext_addr);
	}

	return 0;
}

static int cmd_ieee802154_set_short_addr(const struct shell *sh,
					 size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	uint16_t short_addr; /* in CPU byte order */

	if (argc < 2) {
		shell_help(sh);
		return -ENOEXEC;
	}

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	short_addr = (uint16_t)atoi(argv[1]);

	if (net_mgmt(NET_REQUEST_IEEE802154_SET_SHORT_ADDR, iface,
		     &short_addr, sizeof(uint16_t))) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not set short address %u\n", short_addr);

		return -ENOEXEC;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "Short address %u set\n", short_addr);
	}

	return 0;
}

static int cmd_ieee802154_get_short_addr(const struct shell *sh,
					 size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	uint16_t short_addr; /* in CPU byte order */

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	if (net_mgmt(NET_REQUEST_IEEE802154_GET_SHORT_ADDR, iface,
		     &short_addr, sizeof(uint16_t))) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not get short address\n");

		return -ENOEXEC;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "Short address %u\n", short_addr);
	}

	return 0;
}

static int cmd_ieee802154_set_tx_power(const struct shell *sh,
				       size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	int16_t tx_power;

	if (argc < 2) {
		shell_help(sh);
		return -ENOEXEC;
	}

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	tx_power = (int16_t)atoi(argv[1]);

	if (net_mgmt(NET_REQUEST_IEEE802154_SET_TX_POWER, iface,
		     &tx_power, sizeof(int16_t))) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not set TX power %d\n", tx_power);

		return -ENOEXEC;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "TX power %d set\n", tx_power);
	}

	return 0;
}

static int cmd_ieee802154_get_tx_power(const struct shell *sh,
				       size_t argc, char *argv[])
{
	struct net_if *iface = net_if_get_ieee802154();
	int16_t tx_power;

	if (!iface) {
		shell_fprintf(sh, SHELL_INFO,
			      "No IEEE 802.15.4 interface found.\n");
		return -ENOEXEC;
	}

	if (net_mgmt(NET_REQUEST_IEEE802154_GET_TX_POWER, iface,
		     &tx_power, sizeof(int16_t))) {
		shell_fprintf(sh, SHELL_WARNING,
			      "Could not get TX power\n");

		return -ENOEXEC;
	} else {
		shell_fprintf(sh, SHELL_NORMAL,
			      "TX power (in dbm) %d\n", tx_power);
	}

	return 0;
}

SHELL_STATIC_SUBCMD_SET_CREATE(ieee802154_commands,
	SHELL_CMD(ack, NULL,
		  "<set/1 | unset/0> Set auto-ack flag",
		  cmd_ieee802154_ack),
	SHELL_CMD(associate, NULL,
		  "<pan_id> <PAN coordinator short or long address (EUI-64)>",
		  cmd_ieee802154_associate),
	SHELL_CMD(disassociate,	NULL,
		  "Disassociate from network",
		  cmd_ieee802154_disassociate),
	SHELL_CMD(get_chan, NULL,
		  "Get currently used channel",
		  cmd_ieee802154_get_chan),
	SHELL_CMD(get_ext_addr,	NULL,
		  "Get currently used extended address",
		  cmd_ieee802154_get_ext_addr),
	SHELL_CMD(get_pan_id, NULL,
		  "Get currently used PAN id",
		  cmd_ieee802154_get_pan_id),
	SHELL_CMD(get_short_addr, NULL,
		  "Get currently used short address",
		  cmd_ieee802154_get_short_addr),
	SHELL_CMD(get_tx_power,	NULL,
		  "Get currently used TX power",
		  cmd_ieee802154_get_tx_power),
	SHELL_CMD(scan,	NULL,
		  "<passive|active> <channels set n[:m:...]:x|all>"
		  " <per-channel duration in ms>",
		  cmd_ieee802154_scan),
	SHELL_CMD(set_chan, NULL,
		  "<channel> Set used channel",
		  cmd_ieee802154_set_chan),
	SHELL_CMD(set_ext_addr,	NULL,
		  "<long/extended address (EUI-64)> Set extended address",
		  cmd_ieee802154_set_ext_addr),
	SHELL_CMD(set_pan_id, NULL,
		  "<pan_id> Set used PAN id",
		  cmd_ieee802154_set_pan_id),
	SHELL_CMD(set_short_addr, NULL,
		  "<short address> Set short address",
		  cmd_ieee802154_set_short_addr),
	SHELL_CMD(set_tx_power,	NULL,
		  "<-18/-7/-4/-2/0/1/2/3/5> Set TX power",
		  cmd_ieee802154_set_tx_power),
	SHELL_SUBCMD_SET_END
);

SHELL_CMD_REGISTER(ieee802154, &ieee802154_commands, "IEEE 802.15.4 commands",
		   NULL);
