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

#include <stdlib.h>
#include <zephyr/shell/shell.h>
#include <zephyr/bluetooth/mesh.h>

#include "../net.h"
#include "../access.h"
#include "utils.h"
#include <zephyr/bluetooth/mesh/shell.h>

#define CID_NVAL 0xffff

/* Default net & app key values, unless otherwise specified */
extern const uint8_t bt_mesh_shell_default_key[16];

static int cmd_reset(const struct shell *sh, size_t argc, char *argv[])
{
	int err;
	bool reset = false;

	err = bt_mesh_cfg_cli_node_reset(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, &reset);
	if (err) {
		shell_error(sh, "Unable to send Remote Node Reset (err %d)", err);
		return 0;
	}

	if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
		struct bt_mesh_cdb_node *node = bt_mesh_cdb_node_get(bt_mesh_shell_target_ctx.dst);

		if (node) {
			bt_mesh_cdb_node_del(node, true);
		}
	}

	shell_print(sh, "Remote node reset complete");

	return 0;
}

static int cmd_timeout(const struct shell *sh, size_t argc, char *argv[])
{
	int32_t timeout_ms;
	int err = 0;

	if (argc == 2) {
		int32_t timeout_s = shell_strtol(argv[1], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		if (timeout_s < 0 || timeout_s > (INT32_MAX / 1000)) {
			timeout_ms = SYS_FOREVER_MS;
		} else {
			timeout_ms = timeout_s * MSEC_PER_SEC;
		}

		bt_mesh_cfg_cli_timeout_set(timeout_ms);
	}

	timeout_ms = bt_mesh_cfg_cli_timeout_get();
	if (timeout_ms == SYS_FOREVER_MS) {
		shell_print(sh, "Message timeout: forever");
	} else {
		shell_print(sh, "Message timeout: %u seconds", timeout_ms / 1000);
	}

	return 0;
}

static int cmd_get_comp(const struct shell *sh, size_t argc, char *argv[])
{
	NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_RX_SDU_MAX);
	struct bt_mesh_comp_p0_elem elem;
	struct bt_mesh_comp_p0 comp;
	uint8_t page = 0x00;
	int err = 0;

	if (argc > 1) {
		page = shell_strtoul(argv[1], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}
	}

	err = bt_mesh_cfg_cli_comp_data_get(bt_mesh_shell_target_ctx.net_idx,
					bt_mesh_shell_target_ctx.dst, page, &page, &buf);
	if (err) {
		shell_error(sh, "Getting composition failed (err %d)", err);
		return 0;
	}

	if (page != 0x00) {
		shell_print(sh, "Got page 0x%02x. No parser available.", page);
		return 0;
	}

	err = bt_mesh_comp_p0_get(&comp, &buf);
	if (err) {
		shell_error(sh, "Couldn't parse Composition data (err %d)", err);
		return 0;
	}

	shell_print(sh, "Got Composition Data for 0x%04x:", bt_mesh_shell_target_ctx.dst);
	shell_print(sh, "\tCID      0x%04x", comp.cid);
	shell_print(sh, "\tPID      0x%04x", comp.pid);
	shell_print(sh, "\tVID      0x%04x", comp.vid);
	shell_print(sh, "\tCRPL     0x%04x", comp.crpl);
	shell_print(sh, "\tFeatures 0x%04x", comp.feat);

	while (bt_mesh_comp_p0_elem_pull(&comp, &elem)) {
		int i;

		shell_print(sh, "\tElement @ 0x%04x:", elem.loc);

		if (elem.nsig) {
			shell_print(sh, "\t\tSIG Models:");
		} else {
			shell_print(sh, "\t\tNo SIG Models");
		}

		for (i = 0; i < elem.nsig; i++) {
			uint16_t mod_id = bt_mesh_comp_p0_elem_mod(&elem, i);

			shell_print(sh, "\t\t\t0x%04x", mod_id);
		}

		if (elem.nvnd) {
			shell_print(sh, "\t\tVendor Models:");
		} else {
			shell_print(sh, "\t\tNo Vendor Models");
		}

		for (i = 0; i < elem.nvnd; i++) {
			struct bt_mesh_mod_id_vnd mod = bt_mesh_comp_p0_elem_mod_vnd(&elem, i);

			shell_print(sh, "\t\t\tCompany 0x%04x: 0x%04x", mod.company, mod.id);
		}
	}

	if (buf.len) {
		shell_print(sh, "\t\t...truncated data!");
	}

	return 0;
}

static int cmd_beacon(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t status;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_beacon_get(bt_mesh_shell_target_ctx.net_idx,
					     bt_mesh_shell_target_ctx.dst, &status);
	} else {
		uint8_t val = shell_strtobool(argv[1], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_beacon_set(bt_mesh_shell_target_ctx.net_idx,
					     bt_mesh_shell_target_ctx.dst, val, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Beacon Get/Set message (err %d)", err);
		return 0;
	}

	shell_print(sh, "Beacon state is 0x%02x", status);

	return 0;
}

static int cmd_ttl(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t ttl;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_ttl_get(bt_mesh_shell_target_ctx.net_idx,
					  bt_mesh_shell_target_ctx.dst, &ttl);
	} else {
		uint8_t val = shell_strtoul(argv[1], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_ttl_set(bt_mesh_shell_target_ctx.net_idx,
					  bt_mesh_shell_target_ctx.dst, val, &ttl);
	}

	if (err) {
		shell_error(sh, "Unable to send Default TTL Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "Default TTL is 0x%02x", ttl);

	return 0;
}

static int cmd_friend(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t frnd;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_friend_get(bt_mesh_shell_target_ctx.net_idx,
					     bt_mesh_shell_target_ctx.dst, &frnd);
	} else {
		uint8_t val = shell_strtobool(argv[1], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_friend_set(bt_mesh_shell_target_ctx.net_idx,
					     bt_mesh_shell_target_ctx.dst, val, &frnd);
	}

	if (err) {
		shell_error(sh, "Unable to send Friend Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "Friend is set to 0x%02x", frnd);

	return 0;
}

static int cmd_gatt_proxy(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t proxy;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_gatt_proxy_get(bt_mesh_shell_target_ctx.net_idx,
						 bt_mesh_shell_target_ctx.dst, &proxy);
	} else {
		uint8_t val = shell_strtobool(argv[1], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_gatt_proxy_set(bt_mesh_shell_target_ctx.net_idx,
						 bt_mesh_shell_target_ctx.dst, val, &proxy);
	}

	if (err) {
		shell_print(sh, "Unable to send GATT Proxy Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "GATT Proxy is set to 0x%02x", proxy);

	return 0;
}

static int cmd_polltimeout_get(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t lpn_address;
	int32_t poll_timeout;
	int err = 0;

	lpn_address = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_lpn_timeout_get(bt_mesh_shell_target_ctx.net_idx,
					  bt_mesh_shell_target_ctx.dst, lpn_address, &poll_timeout);
	if (err) {
		shell_error(sh, "Unable to send LPN PollTimeout Get (err %d)", err);
		return 0;
	}

	shell_print(sh, "PollTimeout value %d", poll_timeout);

	return 0;
}

static int cmd_net_transmit(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t transmit;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_net_transmit_get(bt_mesh_shell_target_ctx.net_idx,
						   bt_mesh_shell_target_ctx.dst, &transmit);
	} else {
		if (argc != 3) {
			shell_warn(sh, "Wrong number of input arguments"
					"(2 arguments are required)");
			return -EINVAL;
		}

		uint8_t count, interval, new_transmit;

		count = shell_strtoul(argv[1], 0, &err);
		interval = shell_strtoul(argv[2], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		new_transmit = BT_MESH_TRANSMIT(count, interval);

		err = bt_mesh_cfg_cli_net_transmit_set(bt_mesh_shell_target_ctx.net_idx,
						   bt_mesh_shell_target_ctx.dst, new_transmit,
						   &transmit);
	}

	if (err) {
		shell_error(sh, "Unable to send network transmit Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "Transmit 0x%02x (count %u interval %ums)", transmit,
		    BT_MESH_TRANSMIT_COUNT(transmit), BT_MESH_TRANSMIT_INT(transmit));

	return 0;
}

static int cmd_relay(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t relay, transmit;
	int err = 0;

	if (argc < 2) {
		err = bt_mesh_cfg_cli_relay_get(bt_mesh_shell_target_ctx.net_idx,
					    bt_mesh_shell_target_ctx.dst, &relay, &transmit);
	} else {
		uint8_t count, interval, new_transmit;
		uint8_t val = shell_strtobool(argv[1], 0, &err);

		if (val) {
			if (argc > 2) {
				count = shell_strtoul(argv[2], 0, &err);
			} else {
				count = 2U;
			}

			if (argc > 3) {
				interval = shell_strtoul(argv[3], 0, &err);
			} else {
				interval = 20U;
			}

			new_transmit = BT_MESH_TRANSMIT(count, interval);
		} else {
			new_transmit = 0U;
		}

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_relay_set(bt_mesh_shell_target_ctx.net_idx,
					    bt_mesh_shell_target_ctx.dst, val, new_transmit, &relay,
					    &transmit);
	}

	if (err) {
		shell_error(sh, "Unable to send Relay Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "Relay is 0x%02x, Transmit 0x%02x (count %u interval %ums)", relay,
		    transmit, BT_MESH_TRANSMIT_COUNT(transmit), BT_MESH_TRANSMIT_INT(transmit));

	return 0;
}

static int cmd_net_key_add(const struct shell *sh, size_t argc, char *argv[])
{
	bool has_key_val = (argc > 2);
	uint8_t key_val[16];
	uint16_t key_net_idx;
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (has_key_val) {
		size_t len;

		len = hex2bin(argv[2], strlen(argv[2]), key_val, sizeof(key_val));
		(void)memset(key_val + len, 0, sizeof(key_val) - len);
	} else {
		memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
	}

	if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
		struct bt_mesh_cdb_subnet *subnet;

		subnet = bt_mesh_cdb_subnet_get(key_net_idx);
		if (subnet) {
			if (has_key_val) {
				shell_error(sh, "Subnet 0x%03x already has a value", key_net_idx);
				return 0;
			}

			memcpy(key_val, subnet->keys[0].net_key, 16);
		} else {
			subnet = bt_mesh_cdb_subnet_alloc(key_net_idx);
			if (!subnet) {
				shell_error(sh, "No space for subnet in cdb");
				return 0;
			}

			memcpy(subnet->keys[0].net_key, key_val, 16);
			bt_mesh_cdb_subnet_store(subnet);
		}
	}

	err = bt_mesh_cfg_cli_net_key_add(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, key_net_idx, key_val, &status);
	if (err) {
		shell_print(sh, "Unable to send NetKey Add (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "NetKeyAdd failed with status 0x%02x", status);
	} else {
		shell_print(sh, "NetKey added with NetKey Index 0x%03x", key_net_idx);
	}

	return 0;
}

static int cmd_net_key_update(const struct shell *sh, size_t argc, char *argv[])
{
	bool has_key_val = (argc > 2);
	uint8_t key_val[16];
	uint16_t key_net_idx;
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (has_key_val) {
		size_t len;

		len = hex2bin(argv[2], strlen(argv[2]), key_val, sizeof(key_val));
		(void)memset(key_val + len, 0, sizeof(key_val) - len);
	} else {
		memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
	}

	err = bt_mesh_cfg_cli_net_key_update(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, key_net_idx, key_val,
					 &status);
	if (err) {
		shell_print(sh, "Unable to send NetKey Update (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "NetKeyUpdate failed with status 0x%02x", status);
	} else {
		shell_print(sh, "NetKey updated with NetKey Index 0x%03x", key_net_idx);
	}

	return 0;
}

static int cmd_net_key_get(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t keys[16];
	size_t cnt;
	int err, i;

	cnt = ARRAY_SIZE(keys);

	err = bt_mesh_cfg_cli_net_key_get(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, keys, &cnt);
	if (err) {
		shell_print(sh, "Unable to send NetKeyGet (err %d)", err);
		return 0;
	}

	shell_print(sh, "NetKeys known by 0x%04x:", bt_mesh_shell_target_ctx.dst);
	for (i = 0; i < cnt; i++) {
		shell_print(sh, "\t0x%03x", keys[i]);
	}

	return 0;
}

static int cmd_net_key_del(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t key_net_idx;
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_net_key_del(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, key_net_idx, &status);
	if (err) {
		shell_print(sh, "Unable to send NetKeyDel (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "NetKeyDel failed with status 0x%02x", status);
	} else {
		shell_print(sh, "NetKey 0x%03x deleted", key_net_idx);
	}

	return 0;
}

static int cmd_app_key_add(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t key_val[16];
	uint16_t key_net_idx, key_app_idx;
	bool has_key_val = (argc > 3);
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	key_app_idx = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (has_key_val) {
		size_t len;

		len = hex2bin(argv[3], strlen(argv[3]), key_val, sizeof(key_val));
		(void)memset(key_val + len, 0, sizeof(key_val) - len);
	} else {
		memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
	}

	if (IS_ENABLED(CONFIG_BT_MESH_CDB)) {
		struct bt_mesh_cdb_app_key *app_key;

		app_key = bt_mesh_cdb_app_key_get(key_app_idx);
		if (app_key) {
			if (has_key_val) {
				shell_error(sh, "App key 0x%03x already has a value", key_app_idx);
				return 0;
			}

			memcpy(key_val, app_key->keys[0].app_key, 16);
		} else {
			app_key = bt_mesh_cdb_app_key_alloc(key_net_idx, key_app_idx);
			if (!app_key) {
				shell_error(sh, "No space for app key in cdb");
				return 0;
			}

			memcpy(app_key->keys[0].app_key, key_val, 16);
			bt_mesh_cdb_app_key_store(app_key);
		}
	}

	err = bt_mesh_cfg_cli_app_key_add(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
				      key_val, &status);
	if (err) {
		shell_error(sh, "Unable to send App Key Add (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "AppKeyAdd failed with status 0x%02x", status);
	} else {
		shell_print(sh, "AppKey added, NetKeyIndex 0x%04x AppKeyIndex 0x%04x", key_net_idx,
			    key_app_idx);
	}

	return 0;
}

static int cmd_app_key_upd(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t key_val[16];
	uint16_t key_net_idx, key_app_idx;
	bool has_key_val = (argc > 3);
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	key_app_idx = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (has_key_val) {
		size_t len;

		len = hex2bin(argv[3], strlen(argv[3]), key_val, sizeof(key_val));
		(void)memset(key_val + len, 0, sizeof(key_val) - len);
	} else {
		memcpy(key_val, bt_mesh_shell_default_key, sizeof(key_val));
	}

	err = bt_mesh_cfg_cli_app_key_update(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
					 key_val, &status);
	if (err) {
		shell_error(sh, "Unable to send App Key Update (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "AppKey update failed with status 0x%02x", status);
	} else {
		shell_print(sh, "AppKey updated, NetKeyIndex 0x%04x AppKeyIndex 0x%04x",
			    key_net_idx, key_app_idx);
	}

	return 0;
}

static int cmd_app_key_get(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t net_idx;
	uint16_t keys[16];
	size_t cnt;
	uint8_t status;
	int err = 0;
	int i;

	cnt = ARRAY_SIZE(keys);
	net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_app_key_get(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, net_idx, &status, keys, &cnt);
	if (err) {
		shell_print(sh, "Unable to send AppKeyGet (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "AppKeyGet failed with status 0x%02x", status);
		return 0;
	}

	shell_print(sh, "AppKeys for NetKey 0x%03x known by 0x%04x:", net_idx,
		    bt_mesh_shell_target_ctx.dst);
	for (i = 0; i < cnt; i++) {
		shell_print(sh, "\t0x%03x", keys[i]);
	}

	return 0;
}

static int cmd_node_id(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t net_idx;
	uint8_t status, identify;
	int err = 0;

	net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc <= 2) {
		printk("ANders\n");
		err = bt_mesh_cfg_cli_node_identity_get(bt_mesh_shell_target_ctx.net_idx,
						    bt_mesh_shell_target_ctx.dst, net_idx, &status,
						    &identify);
		if (err) {
			shell_print(sh, "Unable to send Node Identify Get (err %d)", err);
			return 0;
		}
	} else {
		uint8_t new_identify = shell_strtoul(argv[2], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_node_identity_set(bt_mesh_shell_target_ctx.net_idx,
						    bt_mesh_shell_target_ctx.dst, net_idx,
						    new_identify, &status, &identify);
		if (err) {
			shell_print(sh, "Unable to send Node Identify Set (err %d)", err);
			return 0;
		}
	}

	if (status) {
		shell_print(sh, "Node Identify Get/Set failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Node Identify Get/Set successful with identify 0x%02x", identify);
	}

	return 0;
}

static int cmd_app_key_del(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t key_net_idx, key_app_idx;
	uint8_t status;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	key_app_idx = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_app_key_del(bt_mesh_shell_target_ctx.net_idx,
				      bt_mesh_shell_target_ctx.dst, key_net_idx, key_app_idx,
				      &status);
	if (err) {
		shell_error(sh, "Unable to send App Key del(err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "AppKeyDel failed with status 0x%02x", status);
	} else {
		shell_print(sh, "AppKey deleted, NetKeyIndex 0x%04x AppKeyIndex 0x%04x",
			    key_net_idx, key_app_idx);
	}

	return 0;
}

static int cmd_mod_app_bind(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, mod_app_idx, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	mod_app_idx = shell_strtoul(argv[2], 0, &err);
	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_app_bind_vnd(bt_mesh_shell_target_ctx.net_idx,
						   bt_mesh_shell_target_ctx.dst, elem_addr,
						   mod_app_idx, mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_app_bind(bt_mesh_shell_target_ctx.net_idx,
					       bt_mesh_shell_target_ctx.dst, elem_addr, mod_app_idx,
					       mod_id, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model App Bind (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model App Bind failed with status 0x%02x", status);
	} else {
		shell_print(sh, "AppKey successfully bound");
	}

	return 0;
}

static int cmd_mod_app_unbind(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, mod_app_idx, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	mod_app_idx = shell_strtoul(argv[2], 0, &err);
	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_app_unbind_vnd(bt_mesh_shell_target_ctx.net_idx,
						     bt_mesh_shell_target_ctx.dst, elem_addr,
						     mod_app_idx, mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_app_unbind(bt_mesh_shell_target_ctx.net_idx,
						 bt_mesh_shell_target_ctx.dst, elem_addr,
						 mod_app_idx, mod_id, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model App Unbind (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model App Unbind failed with status 0x%02x", status);
	} else {
		shell_print(sh, "AppKey successfully unbound");
	}

	return 0;
}

static int cmd_mod_app_get(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, mod_id, cid;
	uint16_t apps[16];
	uint8_t status;
	size_t cnt;
	int err = 0;
	int i;

	cnt = ARRAY_SIZE(apps);
	elem_addr = shell_strtoul(argv[1], 0, &err);
	mod_id = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 3) {
		cid = shell_strtoul(argv[3], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_app_get_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
						  cid, &status, apps, &cnt);
	} else {
		err = bt_mesh_cfg_cli_mod_app_get(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
					      &status, apps, &cnt);
	}

	if (err) {
		shell_error(sh, "Unable to send Model App Get (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model App Get failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Apps bound to Element 0x%04x, Model 0x%04x %s:", elem_addr, mod_id,
			    argc > 3 ? argv[3] : "(SIG)");

		if (!cnt) {
			shell_print(sh, "\tNone.");
		}

		for (i = 0; i < cnt; i++) {
			shell_print(sh, "\t0x%04x", apps[i]);
		}
	}

	return 0;
}

static int cmd_mod_sub_add(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	sub_addr = shell_strtoul(argv[2], 0, &err);
	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_add_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
						  mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_add(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
					      mod_id, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Add (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Add failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Model subscription was successful");
	}

	return 0;
}

static int cmd_mod_sub_del(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	sub_addr = shell_strtoul(argv[2], 0, &err);
	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_del_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
						  mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_del(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, elem_addr, sub_addr,
					      mod_id, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Delete (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Delete failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Model subscription deltion was successful");
	}

	return 0;
}

static int cmd_mod_sub_add_va(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t label[16];
	uint8_t status;
	size_t len;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);

	len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
	(void)memset(label + len, 0, sizeof(label) - len);

	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_va_add_vnd(bt_mesh_shell_target_ctx.net_idx,
						     bt_mesh_shell_target_ctx.dst, elem_addr, label,
						     mod_id, cid, &sub_addr, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_va_add(bt_mesh_shell_target_ctx.net_idx,
						 bt_mesh_shell_target_ctx.dst, elem_addr, label,
						 mod_id, &sub_addr, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Mod Sub VA Add (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Mod Sub VA Add failed with status 0x%02x", status);
	} else {
		shell_print(sh, "0x%04x subscribed to Label UUID %s (va 0x%04x)", elem_addr,
			    argv[2], sub_addr);
	}

	return 0;
}

static int cmd_mod_sub_del_va(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t label[16];
	uint8_t status;
	size_t len;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);

	len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
	(void)memset(label + len, 0, sizeof(label) - len);

	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_va_del_vnd(bt_mesh_shell_target_ctx.net_idx,
						     bt_mesh_shell_target_ctx.dst, elem_addr, label,
						     mod_id, cid, &sub_addr, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_va_del(bt_mesh_shell_target_ctx.net_idx,
						 bt_mesh_shell_target_ctx.dst, elem_addr, label,
						 mod_id, &sub_addr, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Delete (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Delete failed with status 0x%02x", status);
	} else {
		shell_print(sh, "0x%04x unsubscribed from Label UUID %s (va 0x%04x)", elem_addr,
			    argv[2], sub_addr);
	}

	return 0;
}

static int cmd_mod_sub_ow(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	sub_addr = shell_strtoul(argv[2], 0, &err);
	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_overwrite_vnd(bt_mesh_shell_target_ctx.net_idx,
							bt_mesh_shell_target_ctx.dst, elem_addr,
							sub_addr, mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_overwrite(bt_mesh_shell_target_ctx.net_idx,
						    bt_mesh_shell_target_ctx.dst, elem_addr,
						    sub_addr, mod_id, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Overwrite (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Overwrite failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Model subscription overwrite was successful");
	}

	return 0;
}

static int cmd_mod_sub_ow_va(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, sub_addr, mod_id, cid;
	uint8_t label[16];
	uint8_t status;
	size_t len;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);

	len = hex2bin(argv[2], strlen(argv[2]), label, sizeof(label));
	(void)memset(label + len, 0, sizeof(label) - len);

	mod_id = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 4) {
		cid = shell_strtoul(argv[4], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_va_overwrite_vnd(bt_mesh_shell_target_ctx.net_idx,
							   bt_mesh_shell_target_ctx.dst, elem_addr,
							   label, mod_id, cid, &sub_addr, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_va_overwrite(bt_mesh_shell_target_ctx.net_idx,
						       bt_mesh_shell_target_ctx.dst, elem_addr,
						       label, mod_id, &sub_addr, &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Mod Sub VA Overwrite (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Mod Sub VA Overwrite failed with status 0x%02x", status);
	} else {
		shell_print(sh, "0x%04x overwrite to Label UUID %s (va 0x%04x)", elem_addr, argv[2],
			    sub_addr);
	}

	return 0;
}

static int cmd_mod_sub_del_all(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, mod_id, cid;
	uint8_t status;
	int err = 0;

	elem_addr = shell_strtoul(argv[1], 0, &err);
	mod_id = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 3) {
		cid = shell_strtoul(argv[3], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_del_all_vnd(bt_mesh_shell_target_ctx.net_idx,
						      bt_mesh_shell_target_ctx.dst, elem_addr,
						      mod_id, cid, &status);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_del_all(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
						  &status);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Delete All (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Delete All failed with status 0x%02x", status);
	} else {
		shell_print(sh, "Model subscription deltion all was successful");
	}

	return 0;
}

static int cmd_mod_sub_get(const struct shell *sh, size_t argc, char *argv[])
{
	uint16_t elem_addr, mod_id, cid;
	uint16_t subs[16];
	uint8_t status;
	size_t cnt;
	int err = 0;
	int i;

	cnt = ARRAY_SIZE(subs);
	elem_addr = shell_strtoul(argv[1], 0, &err);
	mod_id = shell_strtoul(argv[2], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 3) {
		cid = shell_strtoul(argv[3], 0, &err);
		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_mod_sub_get_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
						  cid, &status, subs, &cnt);
	} else {
		err = bt_mesh_cfg_cli_mod_sub_get(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, elem_addr, mod_id,
					      &status, subs, &cnt);
	}

	if (err) {
		shell_error(sh, "Unable to send Model Subscription Get (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Subscription Get failed with status 0x%02x", status);
	} else {
		shell_print(sh,
			    "Model Subscriptions for Element 0x%04x, Model 0x%04x %s:", elem_addr,
			    mod_id, argc > 3 ? argv[3] : "(SIG)");

		if (!cnt) {
			shell_print(sh, "\tNone.");
		}

		for (i = 0; i < cnt; i++) {
			shell_print(sh, "\t0x%04x", subs[i]);
		}
	}

	return 0;
}

static int cmd_krp(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t status, phase;
	uint16_t key_net_idx;
	int err = 0;

	key_net_idx = shell_strtoul(argv[1], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc < 3) {
		err = bt_mesh_cfg_cli_krp_get(bt_mesh_shell_target_ctx.net_idx,
					  bt_mesh_shell_target_ctx.dst, key_net_idx, &status,
					  &phase);
	} else {
		uint16_t trans = shell_strtoul(argv[2], 0, &err);

		if (err) {
			shell_warn(sh, "Unable to parse input string argument");
			return err;
		}

		err = bt_mesh_cfg_cli_krp_set(bt_mesh_shell_target_ctx.net_idx,
					  bt_mesh_shell_target_ctx.dst, key_net_idx, trans, &status,
					  &phase);
	}

	if (err) {
		shell_error(sh, "Unable to send key refresh phase Get/Set (err %d)", err);
		return 0;
	}

	shell_print(sh, "Key refresh phase Get/Set with status 0x%02x and phase 0x%02x", status,
		    phase);

	return 0;
}

static int mod_pub_get(const struct shell *sh, uint16_t addr, uint16_t mod_id, uint16_t cid)
{
	struct bt_mesh_cfg_cli_mod_pub pub;
	uint8_t status;
	int err;

	if (cid == CID_NVAL) {
		err = bt_mesh_cfg_cli_mod_pub_get(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, addr, mod_id, &pub,
					      &status);
	} else {
		err = bt_mesh_cfg_cli_mod_pub_get_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, addr, mod_id, cid,
						  &pub, &status);
	}

	if (err) {
		shell_error(sh, "Model Publication Get failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Publication Get failed (status 0x%02x)", status);
		return 0;
	}

	shell_print(sh,
		    "Model Publication for Element 0x%04x, Model 0x%04x:\n"
		    "\tPublish Address:                0x%04x\n"
		    "\tAppKeyIndex:                    0x%04x\n"
		    "\tCredential Flag:                %u\n"
		    "\tPublishTTL:                     %u\n"
		    "\tPublishPeriod:                  0x%02x\n"
		    "\tPublishRetransmitCount:         %u\n"
		    "\tPublishRetransmitInterval:      %ums",
		    addr, mod_id, pub.addr, pub.app_idx, pub.cred_flag, pub.ttl, pub.period,
		    BT_MESH_PUB_TRANSMIT_COUNT(pub.transmit),
		    BT_MESH_PUB_TRANSMIT_INT(pub.transmit));

	return 0;
}

static int mod_pub_set(const struct shell *sh, uint16_t addr, bool is_va, uint16_t mod_id,
		       uint16_t cid, char *argv[])
{
	struct bt_mesh_cfg_cli_mod_pub pub;
	uint8_t status, count;
	uint16_t interval;
	uint8_t uuid[16];
	uint8_t len;
	int err = 0;

	if (!is_va) {
		pub.addr = shell_strtoul(argv[0], 0, &err);
		pub.uuid = NULL;
	} else {
		len = hex2bin(argv[0], strlen(argv[0]), uuid, sizeof(uuid));
		memset(uuid + len, 0, sizeof(uuid) - len);
		pub.uuid = (const uint8_t *)&uuid;
	}

	pub.app_idx = shell_strtoul(argv[1], 0, &err);
	pub.cred_flag = shell_strtobool(argv[2], 0, &err);
	pub.ttl = shell_strtoul(argv[3], 0, &err);
	pub.period = shell_strtoul(argv[4], 0, &err);

	count = shell_strtoul(argv[5], 0, &err);
	if (count > 7) {
		shell_print(sh, "Invalid retransmit count");
		return -EINVAL;
	}

	interval = shell_strtoul(argv[6], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (interval > (31 * 50) || (interval % 50)) {
		shell_print(sh, "Invalid retransmit interval %u", interval);
		return -EINVAL;
	}

	pub.transmit = BT_MESH_PUB_TRANSMIT(count, interval);

	if (cid == CID_NVAL) {
		err = bt_mesh_cfg_cli_mod_pub_set(bt_mesh_shell_target_ctx.net_idx,
					      bt_mesh_shell_target_ctx.dst, addr, mod_id, &pub,
					      &status);
	} else {
		err = bt_mesh_cfg_cli_mod_pub_set_vnd(bt_mesh_shell_target_ctx.net_idx,
						  bt_mesh_shell_target_ctx.dst, addr, mod_id, cid,
						  &pub, &status);
	}

	if (err) {
		shell_error(sh, "Model Publication Set failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Model Publication Set failed (status 0x%02x)", status);
	} else {
		shell_print(sh, "Model Publication successfully set");
	}

	return 0;
}

static int cmd_mod_pub(const struct shell *sh, size_t argc, char *argv[])
{
	int err = 0;
	uint16_t addr, mod_id, cid;

	addr = shell_strtoul(argv[1], 0, &err);
	mod_id = shell_strtoul(argv[2], 0, &err);

	argc -= 3;
	argv += 3;

	if (argc == 1 || argc == 8) {
		cid = shell_strtoul(argv[0], 0, &err);
		argc--;
		argv++;
	} else {
		cid = CID_NVAL;
	}

	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	if (argc > 0) {
		if (argc < 7) {
			shell_warn(sh, "Invalid number of argument");
			return -EINVAL;
		}

		return mod_pub_set(sh, addr, false, mod_id, cid, argv);
	} else {
		return mod_pub_get(sh, addr, mod_id, cid);
	}
}

static int cmd_mod_pub_va(const struct shell *sh, size_t argc, char *argv[])
{
	int err = 0;
	uint16_t addr, mod_id, cid = CID_NVAL;

	addr = shell_strtoul(argv[1], 0, &err);
	mod_id = shell_strtoul(argv[9], 0, &err);

	if (argc > 10) {
		cid = shell_strtoul(argv[10], 0, &err);
	}

	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	argv += 2;

	return mod_pub_set(sh, addr, true, mod_id, cid, argv);
}

static void hb_sub_print(const struct shell *sh, struct bt_mesh_cfg_cli_hb_sub *sub)
{
	shell_print(sh,
		    "Heartbeat Subscription:\n"
		    "\tSource:      0x%04x\n"
		    "\tDestination: 0x%04x\n"
		    "\tPeriodLog:   0x%02x\n"
		    "\tCountLog:    0x%02x\n"
		    "\tMinHops:     %u\n"
		    "\tMaxHops:     %u",
		    sub->src, sub->dst, sub->period, sub->count, sub->min, sub->max);
}

static int hb_sub_get(const struct shell *sh, size_t argc, char *argv[])
{
	struct bt_mesh_cfg_cli_hb_sub sub;
	uint8_t status;
	int err;

	err = bt_mesh_cfg_cli_hb_sub_get(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, &sub, &status);
	if (err) {
		shell_error(sh, "Heartbeat Subscription Get failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Heartbeat Subscription Get failed (status 0x%02x)", status);
	} else {
		hb_sub_print(sh, &sub);
	}

	return 0;
}

static int hb_sub_set(const struct shell *sh, size_t argc, char *argv[])
{
	struct bt_mesh_cfg_cli_hb_sub sub;
	uint8_t status;
	int err = 0;

	sub.src = shell_strtoul(argv[1], 0, &err);
	sub.dst = shell_strtoul(argv[2], 0, &err);
	sub.period = shell_strtoul(argv[3], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_hb_sub_set(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, &sub, &status);
	if (err) {
		shell_error(sh, "Heartbeat Subscription Set failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Heartbeat Subscription Set failed (status 0x%02x)", status);
	} else {
		hb_sub_print(sh, &sub);
	}

	return 0;
}

static int cmd_hb_sub(const struct shell *sh, size_t argc, char *argv[])
{
	if (argc > 1) {
		if (argc < 4) {
			shell_warn(sh, "Invalid number of argument");
			return -EINVAL;
		}

		return hb_sub_set(sh, argc, argv);
	} else {
		return hb_sub_get(sh, argc, argv);
	}
}

static int hb_pub_get(const struct shell *sh, size_t argc, char *argv[])
{
	struct bt_mesh_cfg_cli_hb_pub pub;
	uint8_t status;
	int err;

	err = bt_mesh_cfg_cli_hb_pub_get(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, &pub, &status);
	if (err) {
		shell_error(sh, "Heartbeat Publication Get failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Heartbeat Publication Get failed (status 0x%02x)", status);
		return 0;
	}

	shell_print(sh, "Heartbeat publication:");
	shell_print(sh, "\tdst 0x%04x count 0x%02x period 0x%02x", pub.dst, pub.count, pub.period);
	shell_print(sh, "\tttl 0x%02x feat 0x%04x net_idx 0x%04x", pub.ttl, pub.feat, pub.net_idx);

	return 0;
}

static int hb_pub_set(const struct shell *sh, size_t argc, char *argv[])
{
	struct bt_mesh_cfg_cli_hb_pub pub;
	uint8_t status;
	int err = 0;

	pub.dst = shell_strtoul(argv[1], 0, &err);
	pub.count = shell_strtoul(argv[2], 0, &err);
	pub.period = shell_strtoul(argv[3], 0, &err);
	pub.ttl = shell_strtoul(argv[4], 0, &err);
	pub.feat = shell_strtoul(argv[5], 0, &err);
	pub.net_idx = shell_strtoul(argv[6], 0, &err);
	if (err) {
		shell_warn(sh, "Unable to parse input string argument");
		return err;
	}

	err = bt_mesh_cfg_cli_hb_pub_set(bt_mesh_shell_target_ctx.net_idx,
					 bt_mesh_shell_target_ctx.dst, &pub, &status);
	if (err) {
		shell_error(sh, "Heartbeat Publication Set failed (err %d)", err);
		return 0;
	}

	if (status) {
		shell_print(sh, "Heartbeat Publication Set failed (status 0x%02x)", status);
	} else {
		shell_print(sh, "Heartbeat publication successfully set");
	}

	return 0;
}

static int cmd_hb_pub(const struct shell *sh, size_t argc, char *argv[])
{
	if (argc > 1) {
		if (argc < 7) {
			shell_warn(sh, "Invalid number of argument");
			return -EINVAL;
		}

		return hb_pub_set(sh, argc, argv);
	} else {
		return hb_pub_get(sh, argc, argv);
	}
}

SHELL_STATIC_SUBCMD_SET_CREATE(model_cmds,
	SHELL_CMD_ARG(app-bind, NULL, "<Addr> <AppIndex> <Model ID> [Company ID]",
		      cmd_mod_app_bind, 4, 1),
	SHELL_CMD_ARG(app-get, NULL, "<Elem addr> <Model ID> [Company ID]", cmd_mod_app_get,
		      3, 1),
	SHELL_CMD_ARG(app-unbind, NULL, "<Addr> <AppIndex> <Model ID> [Company ID]",
		      cmd_mod_app_unbind, 4, 1),
	SHELL_CMD_ARG(pub, NULL,
		      "<Addr> <Model ID> [Company ID] [<PubAddr> "
		      "<AppKeyIndex> <Cred: off, on> <TTL> <Period> <Count> <Interval>]",
		      cmd_mod_pub, 3, 1 + 7),
	SHELL_CMD_ARG(pub-va, NULL,
		      "<Addr> <UUID: 16 hex values> "
		      "<AppKeyIndex> <Cred: off, on> <TTL> <Period> <Count> <Interval> "
		      "<Model ID> [Company ID]",
		      cmd_mod_pub_va, 10, 1),
	SHELL_CMD_ARG(sub-add, NULL, "<Elem addr> <Sub addr> <Model ID> [Company ID]",
		      cmd_mod_sub_add, 4, 1),
	SHELL_CMD_ARG(sub-del, NULL, "<Elem addr> <Sub addr> <Model ID> [Company ID]",
		      cmd_mod_sub_del, 4, 1),
	SHELL_CMD_ARG(sub-add-va, NULL,
		      "<Elem addr> <Label UUID> <Model ID> [Company ID]", cmd_mod_sub_add_va, 4, 1),
	SHELL_CMD_ARG(sub-del-va, NULL,
		      "<Elem addr> <Label UUID> <Model ID> [Company ID]", cmd_mod_sub_del_va, 4, 1),
	SHELL_CMD_ARG(sub-ow, NULL, "<Elem addr> <Sub addr> <Model ID> [Company ID]",
		      cmd_mod_sub_ow, 4, 1),
	SHELL_CMD_ARG(sub-ow-va, NULL, "<Elem addr> <Label UUID> <Model ID> [Company ID]",
		      cmd_mod_sub_ow_va, 4, 1),
	SHELL_CMD_ARG(sub-del-all, NULL, "<Elem addr> <Model ID> [Company ID]",
		      cmd_mod_sub_del_all, 3, 1),
	SHELL_CMD_ARG(sub-get, NULL, "<Elem addr> <Model ID> [Company ID]", cmd_mod_sub_get,
		      3, 1),
	SHELL_SUBCMD_SET_END);

SHELL_STATIC_SUBCMD_SET_CREATE(netkey_cmds,
	SHELL_CMD_ARG(add, NULL, "<NetKeyIndex> [Val]", cmd_net_key_add, 2, 1),
	SHELL_CMD_ARG(upd, NULL, "<NetKeyIndex> [Val]", cmd_net_key_update, 2, 1),
	SHELL_CMD_ARG(get, NULL, NULL, cmd_net_key_get, 1, 0),
	SHELL_CMD_ARG(del, NULL, "<NetKeyIndex>", cmd_net_key_del, 2, 0),
	SHELL_SUBCMD_SET_END);

SHELL_STATIC_SUBCMD_SET_CREATE(appkey_cmds,
	SHELL_CMD_ARG(add, NULL, "<NetKeyIndex> <AppKeyIndex> [Val]", cmd_app_key_add,
		      3, 1),
	SHELL_CMD_ARG(upd, NULL, "<NetKeyIndex> <AppKeyIndex> [Val]", cmd_app_key_upd,
		      3, 1),
	SHELL_CMD_ARG(del, NULL, "<NetKeyIndex> <AppKeyIndex>", cmd_app_key_del, 3, 0),
	SHELL_CMD_ARG(get, NULL, "<NetKeyIndex>", cmd_app_key_get, 2, 0),
	SHELL_SUBCMD_SET_END);


SHELL_STATIC_SUBCMD_SET_CREATE(
	cfg_cli_cmds,
	/* Configuration Client Model operations */
	SHELL_CMD_ARG(reset, NULL, NULL, cmd_reset, 1, 0),
	SHELL_CMD_ARG(timeout, NULL, "[Timeout in seconds]", cmd_timeout, 1, 1),
	SHELL_CMD_ARG(get-comp, NULL, "[Page]", cmd_get_comp, 1, 1),
	SHELL_CMD_ARG(beacon, NULL, "[Val: off, on]", cmd_beacon, 1, 1),
	SHELL_CMD_ARG(ttl, NULL, "[TTL: 0x00, 0x02-0x7f]", cmd_ttl, 1, 1),
	SHELL_CMD_ARG(friend, NULL, "[Val: off, on]", cmd_friend, 1, 1),
	SHELL_CMD_ARG(gatt-proxy, NULL, "[Val: off, on]", cmd_gatt_proxy, 1, 1),
	SHELL_CMD_ARG(relay, NULL, "[<Val: off, on> [<Count: 0-7> [Interval: 10-320]]]", cmd_relay,
		      1, 3),
	SHELL_CMD_ARG(node-id, NULL, "<NetKeyIndex> [Identify]", cmd_node_id, 2, 1),
	SHELL_CMD_ARG(polltimeout-get, NULL, "<LPN Address>", cmd_polltimeout_get, 2, 0),
	SHELL_CMD_ARG(net-transmit-param, NULL,
		      "[<Count: 0-7>"
		      " <Interval: 10-320>]",
		      cmd_net_transmit, 1, 2),
	SHELL_CMD_ARG(krp, NULL, "<NetKeyIndex> [Phase]", cmd_krp, 2, 1),
	SHELL_CMD_ARG(hb-sub, NULL, "[<Src> <Dst> <Period>]", cmd_hb_sub, 1, 3),
	SHELL_CMD_ARG(hb-pub, NULL, "[<Dst> <Count> <Period> <TTL> <Features> <NetKeyIndex>]",
		      cmd_hb_pub, 1, 6),
	SHELL_CMD(appkey, &appkey_cmds, "Appkey config commands", bt_mesh_shell_mdl_cmds_help),
	SHELL_CMD(netkey, &netkey_cmds, "Netkey config commands", bt_mesh_shell_mdl_cmds_help),
	SHELL_CMD(model, &model_cmds, "Model config commands", bt_mesh_shell_mdl_cmds_help),
	SHELL_SUBCMD_SET_END);

SHELL_SUBCMD_ADD((mesh, models), cfg, &cfg_cli_cmds, "Config Cli commands",
		 bt_mesh_shell_mdl_cmds_help, 1, 1);
