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

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

#include "utils.h"

#include "../dfu_slot.h"
#include "../dfd_srv_internal.h"
#include "../access.h"

static const struct bt_mesh_model *mod;

static void print_receivers_status(const struct shell *sh, struct bt_mesh_dfd_srv *srv,
				   enum bt_mesh_dfd_status status)
{
	shell_print(sh, "{\"status\": %d, \"target_cnt\": %d}", status, srv->target_cnt);
}

static void print_dfd_status(const struct shell *sh, struct bt_mesh_dfd_srv *srv,
			     enum bt_mesh_dfd_status status)
{
	shell_fprintf(sh, SHELL_NORMAL, "{ \"status\": %d, \"phase\": %d", status,
		      srv->phase);

	if (srv->phase != BT_MESH_DFD_PHASE_IDLE && srv->dfu.xfer.slot) {
		shell_fprintf(sh, SHELL_NORMAL, ", \"group\": %d, \"app_idx\": %d, "
			      "\"ttl\": %d, \"timeout_base\": %d, \"xfer_mode\": %d, "
			      "\"apply\": %d, \"slot_idx\": %d", srv->inputs.group,
			      srv->inputs.app_idx, srv->inputs.ttl, srv->inputs.timeout_base,
			      srv->dfu.xfer.blob.mode, srv->apply, srv->slot_idx);
	}

	shell_print(sh, " }");
}

static void print_fw_status(const struct shell *sh, enum bt_mesh_dfd_status status,
			    uint16_t idx, const uint8_t *fwid, size_t fwid_len)
{
	shell_fprintf(sh, SHELL_NORMAL, "{ \"status\": %d, \"slot_cnt\": %d, \"idx\": %d",
		      status, bt_mesh_dfu_slot_count(), idx);
	if (fwid) {
		shell_fprintf(sh, SHELL_NORMAL, ", \"fwid\": \"");
		for (size_t i = 0; i < fwid_len; i++) {
			shell_fprintf(sh, SHELL_NORMAL, "%02x", fwid[i]);
		}
		shell_fprintf(sh, SHELL_NORMAL, "\"");
	}
	shell_print(sh, " }");
}

static enum bt_mesh_dfu_iter slot_space_cb(const struct bt_mesh_dfu_slot *slot,
					   void *user_data)
{
	size_t *total = user_data;

	*total += slot->size;

	return BT_MESH_DFU_ITER_CONTINUE;
}

static int cmd_dfd_receivers_add(const struct shell *sh, size_t argc, char *argv[])
{
	if (!mod && !bt_mesh_shell_mdl_first_get(BT_MESH_MODEL_ID_DFD_SRV, &mod)) {
		return -ENODEV;
	}

	struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data;

	if (bt_mesh_dfu_cli_is_busy(&dfd_srv->dfu)) {
		print_receivers_status(sh, dfd_srv,
				       BT_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION);
		return -EBUSY;
	}

	char *outer_state, *inner_state;

	char *token = strtok_r(argv[1], ";", &outer_state);

	while (token) {
		char *addr_str = strtok_r(token, ",", &inner_state);
		char *img_idx_str = strtok_r(NULL, ",", &inner_state);
		int err = 0;

		if (addr_str == NULL || img_idx_str == NULL) {
			return -EINVAL;
		}

		uint16_t addr = shell_strtoul(addr_str, 0, &err);
		uint8_t img_idx = shell_strtoul(img_idx_str, 0, &err);

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

		enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_receiver_add(
			dfd_srv, addr, img_idx);

		if (status != BT_MESH_DFD_SUCCESS) {
			print_receivers_status(sh, dfd_srv, status);
			return status == BT_MESH_DFD_ERR_INSUFFICIENT_RESOURCES ?
				-ENOSPC : -EINVAL;
		}

		token = strtok_r(NULL, ";", &outer_state);
	}

	print_receivers_status(sh, dfd_srv, BT_MESH_DFD_SUCCESS);

	return 0;
}

static int cmd_dfd_receivers_delete_all(const struct shell *sh, size_t argc, char *argv[])
{
	if (!mod && !bt_mesh_shell_mdl_first_get(BT_MESH_MODEL_ID_DFD_SRV, &mod)) {
		return -ENODEV;
	}

	struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data;

	enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_receivers_delete_all(
		dfd_srv);

	print_receivers_status(sh, dfd_srv, status);

	if (status != BT_MESH_DFD_SUCCESS) {
		return status == BT_MESH_DFD_ERR_BUSY_WITH_DISTRIBUTION ? -EBUSY : -EINVAL;
	}

	return 0;
}

static int cmd_dfd_receivers_get(const struct shell *sh, size_t argc, char *argv[])
{
	if (!mod && !bt_mesh_shell_mdl_first_get(BT_MESH_MODEL_ID_DFD_SRV, &mod)) {
		return -ENODEV;
	}

	struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data;
	int err = 0;

	uint16_t first = shell_strtoul(argv[1], 0, &err);
	uint16_t cnt = shell_strtoul(argv[2], 0, &err);

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

	if (cnt == 0 || dfd_srv->target_cnt <= first) {
		return -EINVAL;
	}

	cnt = MIN(cnt, dfd_srv->target_cnt - first);
	uint8_t progress = bt_mesh_dfu_cli_progress(&dfd_srv->dfu) / 2;

	shell_print(sh, "{\n\t\"target_cnt\": %d,\n\t\"targets\": {",
		    dfd_srv->target_cnt);
	for (int i = 0; i < cnt; i++) {
		const struct bt_mesh_dfu_target *t = &dfd_srv->targets[i + first];

		shell_print(sh, "\t\t\"%d\": { \"blob_addr\": %d, \"phase\": %d, "
			    "\"status\": %d, \"blob_status\": %d, \"progress\": %d, "
			    "\"img_idx\": %d }%s", i + first, t->blob.addr, t->phase, t->status,
			    t->blob.status, progress, t->img_idx, (i == cnt - 1) ? "" : ",");
	}
	shell_print(sh, "\t}\n}");

	return 0;
}

static int cmd_dfd_capabilities_get(const struct shell *sh, size_t argc, char *argv[])
{
	size_t size = 0;
	/* Remaining size */
	(void)bt_mesh_dfu_slot_foreach(slot_space_cb, &size);
	size = MIN(size, CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE);

	shell_print(sh, "{ \"targets_max\": %d, \"slot_cnt\": %d, \"slot_max_size\": %d, "
		    "\"slot_space\": %d, \"remaining_space\": %d, \"oob_supported\": false }",
		    CONFIG_BT_MESH_DFD_SRV_TARGETS_MAX, CONFIG_BT_MESH_DFU_SLOT_CNT,
		    CONFIG_BT_MESH_DFD_SRV_SLOT_MAX_SIZE, CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE,
		    CONFIG_BT_MESH_DFD_SRV_SLOT_SPACE - size);

	return 0;
}

static int cmd_dfd_get(const struct shell *sh, size_t argc, char *argv[])
{
	if (!mod && !bt_mesh_shell_mdl_first_get(BT_MESH_MODEL_ID_DFD_SRV, &mod)) {
		return -ENODEV;
	}

	struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data;

	print_dfd_status(sh, dfd_srv, BT_MESH_DFD_SUCCESS);

	return 0;
}

static int cmd_dfd_start(const struct shell *sh, size_t argc, char *argv[])
{
	if (!mod && !bt_mesh_shell_mdl_first_get(BT_MESH_MODEL_ID_DFD_SRV, &mod)) {
		return -ENODEV;
	}

	struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data;
	struct bt_mesh_dfd_start_params params;
	int err = 0;

	params.app_idx = shell_strtoul(argv[1], 0, &err);
	params.slot_idx = shell_strtoul(argv[2], 0, &err);
	if (argc > 3) {
		params.group = shell_strtoul(argv[3], 0, &err);
	} else {
		params.group = BT_MESH_ADDR_UNASSIGNED;
	}

	if (argc > 4) {
		params.apply = strcmp(argv[4], "true") ? false : true;
	} else {
		params.apply = true;
	}

	if (argc > 5) {
		params.ttl = shell_strtoul(argv[5], 0, &err);
	} else {
		params.ttl = BT_MESH_TTL_DEFAULT;
	}

	if (argc > 6) {
		params.timeout_base = shell_strtoul(argv[6], 0, &err);
	} else {
		params.timeout_base = 0U;
	}

	if (argc > 7) {
		params.xfer_mode = (enum bt_mesh_blob_xfer_mode)shell_strtoul(argv[7], 0, &err);
	} else {
		params.xfer_mode = BT_MESH_BLOB_XFER_MODE_PUSH;
	}

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

	enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_start(dfd_srv, &params);

	print_dfd_status(sh, dfd_srv, status);
	if (status != BT_MESH_DFD_SUCCESS) {
		return -EINVAL;
	}

	return 0;
}

static int cmd_dfd_suspend(const struct shell *sh, size_t argc, char *argv[])
{
	if (!mod && !bt_mesh_shell_mdl_first_get(BT_MESH_MODEL_ID_DFD_SRV, &mod)) {
		return -ENODEV;
	}

	struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data;

	enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_suspend(dfd_srv);

	print_dfd_status(sh, dfd_srv, status);
	if (status != BT_MESH_DFD_SUCCESS) {
		return -EINVAL;
	}

	return 0;
}

static int cmd_dfd_cancel(const struct shell *sh, size_t argc, char *argv[])
{
	if (!mod && !bt_mesh_shell_mdl_first_get(BT_MESH_MODEL_ID_DFD_SRV, &mod)) {
		return -ENODEV;
	}

	struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data;

	enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_cancel(dfd_srv, NULL);

	print_dfd_status(sh, dfd_srv, status);
	if (status != BT_MESH_DFD_SUCCESS) {
		return -EINVAL;
	}

	return 0;
}

static int cmd_dfd_apply(const struct shell *sh, size_t argc, char *argv[])
{
	if (!mod && !bt_mesh_shell_mdl_first_get(BT_MESH_MODEL_ID_DFD_SRV, &mod)) {
		return -ENODEV;
	}

	struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data;

	enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_apply(dfd_srv);

	print_dfd_status(sh, dfd_srv, status);
	if (status != BT_MESH_DFD_SUCCESS) {
		return -EINVAL;
	}

	return 0;
}

static int cmd_dfd_fw_get(const struct shell *sh, size_t argc, char *argv[])
{
	uint8_t fwid[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
	size_t hexlen = strlen(argv[1]);
	size_t fwid_len = hex2bin(argv[1], hexlen, fwid, CONFIG_BT_MESH_DFU_FWID_MAXLEN);

	if (fwid_len != ((hexlen + 1) / 2)) {
		return -EINVAL;
	}

	int idx = bt_mesh_dfu_slot_get(fwid, fwid_len, NULL);

	if (idx >= 0) {
		print_fw_status(sh, BT_MESH_DFD_SUCCESS, idx, fwid, fwid_len);
	} else {
		print_fw_status(sh, BT_MESH_DFD_ERR_FW_NOT_FOUND, 0xffff, fwid, fwid_len);
		return -ENOENT;
	}

	return 0;
}

static int cmd_dfd_fw_get_by_idx(const struct shell *sh, size_t argc, char *argv[])
{
	int err = 0;
	uint16_t idx = shell_strtoul(argv[1], 0, &err);
	const struct bt_mesh_dfu_slot *slot = bt_mesh_dfu_slot_at(idx);

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

	if (slot) {
		print_fw_status(sh, BT_MESH_DFD_SUCCESS, idx, slot->fwid, slot->fwid_len);
	} else {
		print_fw_status(sh, BT_MESH_DFD_ERR_FW_NOT_FOUND, idx, NULL, 0);
		return -ENOENT;
	}

	return 0;
}

static int cmd_dfd_fw_delete(const struct shell *sh, size_t argc, char *argv[])
{
	if (!mod && !bt_mesh_shell_mdl_first_get(BT_MESH_MODEL_ID_DFD_SRV, &mod)) {
		return -ENODEV;
	}

	struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data;

	uint8_t fwid_buf[CONFIG_BT_MESH_DFU_FWID_MAXLEN];
	size_t hexlen = strlen(argv[1]);
	size_t fwid_len = hex2bin(argv[1], hexlen, fwid_buf, CONFIG_BT_MESH_DFU_FWID_MAXLEN);

	if (fwid_len != ((hexlen + 1) / 2)) {
		return -EINVAL;
	}

	const uint8_t *fwid = &fwid_buf[0];

	enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_fw_delete(dfd_srv,
								   &fwid_len, &fwid);

	print_fw_status(sh, status, 0xffff, fwid, fwid_len);

	if (status != BT_MESH_DFD_SUCCESS) {
		return -EINVAL;
	}

	return 0;
}

static int cmd_dfd_fw_delete_all(const struct shell *sh, size_t argc, char *argv[])
{
	if (!mod && !bt_mesh_shell_mdl_first_get(BT_MESH_MODEL_ID_DFD_SRV, &mod)) {
		return -ENODEV;
	}

	struct bt_mesh_dfd_srv *dfd_srv = mod->rt->user_data;

	enum bt_mesh_dfd_status status = bt_mesh_dfd_srv_fw_delete_all(dfd_srv);

	print_fw_status(sh, status, 0xffff, NULL, 0);

	if (status != BT_MESH_DFD_SUCCESS) {
		return -EINVAL;
	}

	return 0;
}

BT_MESH_SHELL_MDL_INSTANCE_CMDS(instance_cmds, BT_MESH_MODEL_ID_DFD_SRV, mod);

SHELL_STATIC_SUBCMD_SET_CREATE(
	dfd_cmds,
	SHELL_CMD_ARG(receivers-add, NULL, "<Addr>,<FwIdx>[;<Addr>,<FwIdx>]...",
		      cmd_dfd_receivers_add, 2, 0),
	SHELL_CMD_ARG(receivers-delete-all, NULL, NULL, cmd_dfd_receivers_delete_all, 1, 0),
	SHELL_CMD_ARG(receivers-get, NULL, "<First> <Count>", cmd_dfd_receivers_get, 3, 0),
	SHELL_CMD_ARG(capabilities-get, NULL, NULL, cmd_dfd_capabilities_get, 1, 0),
	SHELL_CMD_ARG(get, NULL, NULL, cmd_dfd_get, 1, 0),
	SHELL_CMD_ARG(start, NULL,
		      "<AppKeyIdx> <SlotIdx> [<Group> [<PolicyApply> [<TTL> "
		      "[<TimeoutBase> [<XferMode>]]]]]",
		      cmd_dfd_start, 3, 5),
	SHELL_CMD_ARG(suspend, NULL, NULL, cmd_dfd_suspend, 1, 0),
	SHELL_CMD_ARG(cancel, NULL, NULL, cmd_dfd_cancel, 1, 0),
	SHELL_CMD_ARG(apply, NULL, NULL, cmd_dfd_apply, 1, 0),
	SHELL_CMD_ARG(fw-get, NULL, "<FwID>", cmd_dfd_fw_get, 2, 0),
	SHELL_CMD_ARG(fw-get-by-idx, NULL, "<Idx>", cmd_dfd_fw_get_by_idx, 2, 0),
	SHELL_CMD_ARG(fw-delete, NULL, "<FwID>", cmd_dfd_fw_delete, 2, 0),
	SHELL_CMD_ARG(fw-delete-all, NULL, NULL, cmd_dfd_fw_delete_all, 1, 0),
	SHELL_CMD(instance, &instance_cmds, "Instance commands", bt_mesh_shell_mdl_cmds_help),
	SHELL_SUBCMD_SET_END);

SHELL_SUBCMD_ADD((mesh, models), dfd, &dfd_cmds, "Distributor commands",
		 bt_mesh_shell_mdl_cmds_help, 1, 1);
