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

#include <string.h>
#include <zephyr/bluetooth/mesh.h>
#include <zephyr/settings/settings.h>
#include "access.h"
#include "dfu.h"
#include "blob.h"
#include <zephyr/random/random.h>
#include <common/bt_str.h>

#define LOG_LEVEL CONFIG_BT_MESH_DFU_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_mesh_dfu_cli);

#define TARGETS_FOR_EACH(cli, target)                                          \
	SYS_SLIST_FOR_EACH_CONTAINER(                                          \
		(sys_slist_t *)&((cli)->blob.inputs)->targets, target, blob.n)

#define MSG_CTX(cli, dst)                                                      \
	{                                                                      \
		.app_idx = (cli)->blob.inputs->app_idx, .addr = dst,           \
		.send_ttl = (cli)->blob.inputs->ttl,                           \
	}

#define DFU_CLI(blob_cli) CONTAINER_OF(blob_cli, struct bt_mesh_dfu_cli, blob)

BUILD_ASSERT((DFU_UPDATE_START_MSG_MAXLEN + BT_MESH_MODEL_OP_LEN(BT_MESH_DFU_OP_UPDATE_START) +
	      BT_MESH_MIC_SHORT) <= BT_MESH_TX_SDU_MAX,
	     "The Firmware Update Start message does not fit into the maximum outgoing SDU size.");

BUILD_ASSERT((DFU_UPDATE_INFO_STATUS_MSG_MINLEN +
	      BT_MESH_MODEL_OP_LEN(BT_MESH_DFU_OP_UPDATE_INFO_STATUS) + BT_MESH_MIC_SHORT)
	     <= BT_MESH_RX_SDU_MAX,
	     "The Firmware Update Info Status message does not fit into the maximum incoming SDU "
	     "size.");

enum req {
	REQ_NONE,
	REQ_METADATA,
	REQ_IMG,
	REQ_STATUS,
};

enum {
	FLAG_FAILED = BIT(0),
	FLAG_CANCELLED = BIT(1),
	FLAG_SKIP_CAPS_GET = BIT(2),
	FLAG_RESUME = BIT(3),
	FLAG_COMPLETED = BIT(4),
};

enum {
	STATE_IDLE,
	STATE_TRANSFER,
	STATE_REFRESH,
	STATE_VERIFIED,
	STATE_APPLY,
	STATE_APPLIED,
	STATE_CONFIRM,
	STATE_CANCEL,
	STATE_SUSPENDED,
};

static int32_t dfu_cli_timeout = (10 * MSEC_PER_SEC);

static struct bt_mesh_dfu_target *target_get(struct bt_mesh_dfu_cli *cli,
					     uint16_t addr)
{
	struct bt_mesh_dfu_target *target;

	TARGETS_FOR_EACH(cli, target) {
		if (addr == target->blob.addr) {
			return target;
		}
	}

	return NULL;
}

static void target_failed(struct bt_mesh_dfu_cli *cli,
			  struct bt_mesh_dfu_target *target,
			  enum bt_mesh_dfu_status status)
{
	target->status = status;

	LOG_ERR("Target 0x%04x failed: %u", target->blob.addr, status);

	/* Invalidate blob status to prevent the target from being included in
	 * future sending:
	 */
	if (target->blob.status == BT_MESH_BLOB_SUCCESS) {
		target->blob.status = BT_MESH_BLOB_ERR_INTERNAL;
	}

	if (cli->cb && cli->cb->lost_target) {
		cli->cb->lost_target(cli, target);
	}
}

static void dfu_complete(struct bt_mesh_dfu_cli *cli)
{
	LOG_DBG("");

	if (cli->cb && cli->cb->ended) {
		cli->cb->ended(cli, BT_MESH_DFU_SUCCESS);
	}
}

static void dfu_applied(struct bt_mesh_dfu_cli *cli)
{
	LOG_DBG("");

	cli->xfer.state = STATE_APPLIED;

	if (cli->cb && cli->cb->applied) {
		cli->cb->applied(cli);
	}
}

static void dfu_failed(struct bt_mesh_dfu_cli *cli,
		       enum bt_mesh_dfu_status reason)
{
	LOG_DBG("%u", reason);

	cli->xfer.flags |= FLAG_FAILED;

	if (cli->cb && cli->cb->ended) {
		cli->cb->ended(cli, reason);
	}
}

static int req_setup(struct bt_mesh_dfu_cli *cli, enum req type, uint16_t addr,
		     void *params)
{
	if (cli->req.type != REQ_NONE) {
		return -EBUSY;
	}

	cli->req.addr = addr;
	cli->req.params = params;
	cli->req.type = type;

	return 0;
}

static int req_wait(struct bt_mesh_dfu_cli *cli, k_timeout_t timeout)
{
	int err;

	err = k_sem_take(&cli->req.sem, timeout);
	cli->req.type = REQ_NONE;

	return err;
}

static bool targets_active(struct bt_mesh_dfu_cli *cli)
{
	struct bt_mesh_dfu_target *target;

	TARGETS_FOR_EACH(cli, target) {
		if (target->status == BT_MESH_DFU_SUCCESS) {
			return true;
		}
	}

	return false;
}

/*******************************************************************************
 * Blob client
 ******************************************************************************/
static void refresh(struct bt_mesh_dfu_cli *cli);

static void blob_caps(struct bt_mesh_blob_cli *b,
		      const struct bt_mesh_blob_cli_caps *caps)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);
	int err;

	if (!caps) {
		dfu_failed(cli, BT_MESH_DFU_ERR_RESOURCES);
		return;
	}

	cli->xfer.blob.block_size_log = caps->max_block_size_log;
	cli->xfer.blob.chunk_size = caps->max_chunk_size;

	/* If mode is not already set and server reported it supports all modes
	 * default to PUSH, otherwise set value reported by server. If mode
	 * was set and server supports all modes, keep old value; set
	 * reported value otherwise.
	 */
	if (!(cli->xfer.blob.mode & BT_MESH_BLOB_XFER_MODE_ALL)) {
		cli->xfer.blob.mode =
			caps->modes == BT_MESH_BLOB_XFER_MODE_ALL ?
			BT_MESH_BLOB_XFER_MODE_PUSH : caps->modes;
	} else {
		cli->xfer.blob.mode =
			caps->modes == BT_MESH_BLOB_XFER_MODE_ALL ?
			cli->xfer.blob.mode : caps->modes;
	}

	err = bt_mesh_blob_cli_send(b, b->inputs, &cli->xfer.blob, cli->xfer.io);
	if (err) {
		LOG_ERR("Starting BLOB xfer failed: %d", err);
		dfu_failed(cli, BT_MESH_DFU_ERR_BLOB_XFER_BUSY);
	}
}

static void blob_lost_target(struct bt_mesh_blob_cli *b,
			     struct bt_mesh_blob_target *blobt,
			     enum bt_mesh_blob_status reason)
{
	struct bt_mesh_dfu_target *target =
		CONTAINER_OF(blobt, struct bt_mesh_dfu_target, blob);
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);

	if ((cli->xfer.state == STATE_CONFIRM || cli->xfer.state == STATE_APPLY) &&
	    target->effect == BT_MESH_DFU_EFFECT_UNPROV) {
		/* Reset status for such targets to use them in consequent procedures. See sections
		 * 7.1.2.6 and 7.1.2.9 of the MeshDFU.
		 */
		target->blob.status = BT_MESH_BLOB_SUCCESS;
		return;
	}

	target_failed(cli, target, BT_MESH_DFU_ERR_INTERNAL);
}

static void blob_suspended(struct bt_mesh_blob_cli *b)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);

	LOG_DBG("BLOB transfer suspended");

	cli->xfer.state = STATE_SUSPENDED;

	if (cli->cb && cli->cb->suspended) {
		cli->cb->suspended(cli);
	}
}

static void blob_end(struct bt_mesh_blob_cli *b,
		     const struct bt_mesh_blob_xfer *xfer, bool success)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);

	cli->req.img_cb = NULL;

	if (success) {
		refresh(cli);
		return;
	}

	if (cli->xfer.state == STATE_CANCEL) {
		/* The user cancelled the transfer, DFU will end when all
		 * targets have been notified.
		 */
		return;
	}

	if (cli->xfer.state != STATE_TRANSFER) {
		LOG_ERR("Blob failed in invalid state %u", cli->xfer.state);
		return;
	}

	dfu_failed(cli, BT_MESH_DFU_ERR_INTERNAL);
}

const struct bt_mesh_blob_cli_cb _bt_mesh_dfu_cli_blob_handlers = {
	.caps = blob_caps,
	.lost_target = blob_lost_target,
	.suspended = blob_suspended,
	.end = blob_end,
};

/*******************************************************************************
 * Message sending
 ******************************************************************************/

static void tx_start(uint16_t dur, int err, void *cb_data);
static void tx_end(int err, void *cb_data);

static const struct bt_mesh_send_cb send_cb = {
	.start = tx_start,
	.end = tx_end,
};

static void tx_start(uint16_t dur, int err, void *cb_data)
{
	if (err) {
		tx_end(err, cb_data);
	}
}

static void tx_end(int err, void *cb_data)
{
	struct bt_mesh_dfu_cli *cli = cb_data;

	blob_cli_broadcast_tx_complete(&cli->blob);
}

static int info_get(struct bt_mesh_dfu_cli *cli, struct bt_mesh_msg_ctx *ctx,
		    uint8_t idx, uint8_t max_count,
		    const struct bt_mesh_send_cb *cb)
{
	BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_INFO_GET, 2);
	bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_INFO_GET);
	net_buf_simple_add_u8(&buf, idx);
	net_buf_simple_add_u8(&buf, max_count);

	return bt_mesh_model_send(cli->mod, ctx, &buf, cb, cli);
}

static void send_info_get(struct bt_mesh_blob_cli *b, uint16_t dst)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);
	struct bt_mesh_msg_ctx ctx = MSG_CTX(cli, dst);

	cli->req.img_cnt = 0xff;

	info_get(cli, &ctx, 0, cli->req.img_cnt, &send_cb);
}

static void send_update_start(struct bt_mesh_blob_cli *b, uint16_t dst)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);
	struct bt_mesh_msg_ctx ctx = MSG_CTX(cli, dst);
	struct bt_mesh_dfu_target *target;

	if (b->tx.ctx.force_unicast) {
		target = target_get(cli, dst);
	} else {
		target = SYS_SLIST_PEEK_HEAD_CONTAINER(
						(sys_slist_t *)&((cli)->blob.inputs)->targets,
						target, blob.n);
	}

	BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_START,
				 DFU_UPDATE_START_MSG_MAXLEN);
	bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_START);

	net_buf_simple_add_u8(&buf, cli->blob.inputs->ttl);
	net_buf_simple_add_le16(&buf, cli->blob.inputs->timeout_base);
	net_buf_simple_add_le64(&buf, cli->xfer.blob.id);
	net_buf_simple_add_u8(&buf, target->img_idx);
	net_buf_simple_add_mem(&buf, cli->xfer.slot->metadata,
			       cli->xfer.slot->metadata_len);

	bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli);
}

static void send_update_get(struct bt_mesh_blob_cli *b, uint16_t dst)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);
	struct bt_mesh_msg_ctx ctx = MSG_CTX(cli, dst);

	BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_GET, 0);
	bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_GET);

	bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli);
}

static void send_update_cancel(struct bt_mesh_blob_cli *b, uint16_t dst)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);
	struct bt_mesh_msg_ctx ctx = MSG_CTX(cli, dst);

	BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_CANCEL, 0);
	bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_CANCEL);

	bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli);
}

static void send_update_apply(struct bt_mesh_blob_cli *b, uint16_t dst)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);
	struct bt_mesh_msg_ctx ctx = MSG_CTX(cli, dst);

	BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_APPLY, 0);
	bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_APPLY);

	bt_mesh_model_send(cli->mod, &ctx, &buf, &send_cb, cli);
}

/*******************************************************************************
 * Distribution procedure
 ******************************************************************************/
static void transfer(struct bt_mesh_blob_cli *b);
static void apply(struct bt_mesh_dfu_cli *cli);
static void applied(struct bt_mesh_blob_cli *b);
static void confirmed(struct bt_mesh_blob_cli *b);
static void cancelled(struct bt_mesh_blob_cli *b);

static void initiate(struct bt_mesh_dfu_cli *cli)
{
	struct blob_cli_broadcast_ctx tx = {
		.send = send_update_start,
		.next = transfer,
		.acked = true,
	};
	struct bt_mesh_dfu_target *target;
	int img_idx = -1;

	/** If firmware img index is the same for all targets, we can send Firmware Update Start
	 * message using multicast address. Otherwise, it has to be send in a unicast way.
	 */
	TARGETS_FOR_EACH(cli, target) {
		if (img_idx == -1) {
			img_idx = target->img_idx;
		} else if (target->img_idx != img_idx) {
			tx.force_unicast = true;
			break;
		}
	}

	LOG_DBG("");

	cli->op = BT_MESH_DFU_OP_UPDATE_STATUS;
	cli->xfer.state = STATE_TRANSFER;

	blob_cli_broadcast(&cli->blob, &tx);
}

static void skip_targets_from_broadcast(struct bt_mesh_dfu_cli *cli, bool skip)
{
	struct bt_mesh_dfu_target *target;

	TARGETS_FOR_EACH(cli, target) {
		/* If distributor is in the targets list, or target is in Verify phase,
		 * disable it until Retrieve Capabilities and BLOB Transfer procedures
		 * are completed.
		 */
		if (bt_mesh_has_addr(target->blob.addr) ||
		    target->phase == BT_MESH_DFU_PHASE_VERIFY) {
			target->blob.skip = skip;
			break;
		}
	}
}

static bool transfer_skip(struct bt_mesh_dfu_cli *cli)
{
	struct bt_mesh_dfu_target *target;

	TARGETS_FOR_EACH(cli, target) {
		if (!bt_mesh_has_addr(target->blob.addr) || !target->blob.skip) {
			return false;
		}
	}

	return true;
}

static void transfer(struct bt_mesh_blob_cli *b)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);
	int err;

	LOG_DBG("");

	if (!targets_active(cli)) {
		dfu_failed(cli, BT_MESH_DFU_ERR_INTERNAL);
		return;
	}

	skip_targets_from_broadcast(cli, true);

	if (transfer_skip(cli)) {
		/* If distributor only updates itself, or all targets are in Verify phase,
		 * proceed to the refresh step immediately.
		 */
		refresh(cli);
		return;
	}

	if (cli->xfer.flags & FLAG_RESUME) {
		cli->xfer.flags ^= FLAG_RESUME;
		err = bt_mesh_blob_cli_resume(b);
		if (err) {
			LOG_ERR("Resuming BLOB xfer failed: %d", err);
			dfu_failed(cli, BT_MESH_DFU_ERR_BLOB_XFER_BUSY);
		}
	} else if (cli->xfer.flags & FLAG_SKIP_CAPS_GET) {
		cli->xfer.flags ^= FLAG_SKIP_CAPS_GET;
		err = bt_mesh_blob_cli_send(b, b->inputs, &cli->xfer.blob, cli->xfer.io);
		if (err) {
			LOG_ERR("Starting BLOB xfer failed: %d", err);
			dfu_failed(cli, BT_MESH_DFU_ERR_BLOB_XFER_BUSY);
		}
	} else {
		err = bt_mesh_blob_cli_caps_get(&cli->blob, cli->blob.inputs);
		if (err) {
			LOG_ERR("Failed starting blob xfer: %d", err);
			dfu_failed(cli, BT_MESH_DFU_ERR_BLOB_XFER_BUSY);
		}
	}
}

static void refreshed(struct bt_mesh_blob_cli *b)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);

	if (!targets_active(cli)) {
		dfu_failed(cli, BT_MESH_DFU_ERR_INTERNAL);
		return;
	}

	cli->xfer.state = STATE_VERIFIED;
	dfu_complete(cli);
}

static void refresh(struct bt_mesh_dfu_cli *cli)
{
	const struct blob_cli_broadcast_ctx tx = {
		.send = send_update_get,
		.next = refreshed,
		.acked = true
	};

	LOG_DBG("");

	cli->xfer.state = STATE_REFRESH;
	cli->op = BT_MESH_DFU_OP_UPDATE_STATUS;

	/* If distributor is in the targets list, enable it again so it participates in Distribute
	 * Firmware procedure.
	 */
	skip_targets_from_broadcast(cli, false);

	blob_cli_broadcast(&cli->blob, &tx);
}

static void apply(struct bt_mesh_dfu_cli *cli)
{
	const struct blob_cli_broadcast_ctx tx = {
		.send = send_update_apply,
		.next = applied,
		.acked = true
	};

	LOG_DBG("");

	cli->xfer.state = STATE_APPLY;
	cli->op = BT_MESH_DFU_OP_UPDATE_STATUS;

	blob_cli_broadcast(&cli->blob, &tx);
}

static void applied(struct bt_mesh_blob_cli *b)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);

	if (!targets_active(cli)) {
		dfu_failed(cli, BT_MESH_DFU_ERR_INTERNAL);
		return;
	}

	dfu_applied(cli);
}

static enum bt_mesh_dfu_iter target_img_cb(struct bt_mesh_dfu_cli *cli,
					   struct bt_mesh_msg_ctx *ctx,
					   uint8_t idx, uint8_t cnt,
					   const struct bt_mesh_dfu_img *img,
					   void *cb_data)
{
	struct bt_mesh_dfu_target *target;

	if ((img->fwid_len != cli->xfer.slot->fwid_len) ||
	    memcmp(cli->xfer.slot->fwid, img->fwid, img->fwid_len)) {
		return BT_MESH_DFU_ITER_CONTINUE;
	}

	target = target_get(cli, ctx->addr);
	if (target) {
		LOG_DBG("SUCCESS: 0x%04x applied dfu (as image %u)", ctx->addr,
			idx);
		target->phase = BT_MESH_DFU_PHASE_APPLY_SUCCESS;
		blob_cli_broadcast_rsp(&cli->blob, &target->blob);
	} else {
		LOG_WRN("Target 0x%04x not found", ctx->addr);
	}

	return BT_MESH_DFU_ITER_STOP;
}

static void confirm(struct bt_mesh_dfu_cli *cli)
{
	const struct blob_cli_broadcast_ctx tx = {
		.send = send_info_get,
		.next = confirmed,
		.acked = true,
		.optional = true,
	};

	LOG_DBG("");

	cli->op = BT_MESH_DFU_OP_UPDATE_INFO_STATUS;
	cli->req.img_cb = target_img_cb;
	cli->req.ttl = cli->blob.inputs->ttl;

	blob_cli_broadcast(&cli->blob, &tx);
}

static void confirmed(struct bt_mesh_blob_cli *b)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);
	struct bt_mesh_dfu_target *target;
	bool success = false;

	cli->req.img_cb = NULL;

	TARGETS_FOR_EACH(cli, target) {
		if (target->status != BT_MESH_DFU_SUCCESS) {
			/* Target either failed at earlier stage or during confirmation. In any
			 * case, the app is already notified. Don't consider the target here.
			 */
			continue;
		}

		if (target->effect == BT_MESH_DFU_EFFECT_UNPROV) {
			if (!target->blob.acked) {
				success = true;
				continue;
			}

			LOG_DBG("Target 0x%04x still provisioned", target->blob.addr);
			target->phase = BT_MESH_DFU_PHASE_APPLY_FAIL;
			target_failed(cli, target, BT_MESH_DFU_ERR_INTERNAL);
		} else if (!target->blob.acked) {
			LOG_DBG("Target 0x%04x failed to respond", target->blob.addr);
			target->phase = BT_MESH_DFU_PHASE_APPLY_FAIL;
			target_failed(cli, target, BT_MESH_DFU_ERR_INTERNAL);
		} else if (target->status == BT_MESH_DFU_SUCCESS) {
			success = true;
		}
	}

	if (success) {
		cli->xfer.state = STATE_IDLE;
		cli->xfer.flags = FLAG_COMPLETED;

		if (cli->cb && cli->cb->confirmed) {
			cli->cb->confirmed(cli);
		}
	} else {
		dfu_failed(cli, BT_MESH_DFU_ERR_INTERNAL);
	}
}

static void cancel(struct bt_mesh_dfu_cli *cli)
{
	const struct blob_cli_broadcast_ctx tx = {
		.send = send_update_cancel,
		.next = cancelled,
		.acked = true
	};

	LOG_DBG("");

	cli->op = BT_MESH_DFU_OP_UPDATE_STATUS;

	blob_cli_broadcast(&cli->blob, &tx);
}

static void cancelled(struct bt_mesh_blob_cli *b)
{
	struct bt_mesh_dfu_cli *cli = DFU_CLI(b);

	cli->xfer.flags |= FLAG_CANCELLED;
	dfu_failed(cli, BT_MESH_DFU_ERR_INTERNAL);
}

/*******************************************************************************
 * Message handlers
 ******************************************************************************/

static int handle_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
			 struct net_buf_simple *buf)
{
	struct bt_mesh_dfu_cli *cli = mod->user_data;
	enum bt_mesh_dfu_status status;
	enum bt_mesh_dfu_phase phase;
	struct bt_mesh_dfu_target *target;
	uint8_t byte;

	byte = net_buf_simple_pull_u8(buf);
	status = byte & BIT_MASK(3);
	phase = byte >> 5;

	if (cli->req.type == REQ_STATUS && cli->req.addr == ctx->addr) {
		if (cli->req.params) {
			struct bt_mesh_dfu_target_status *rsp = cli->req.params;

			rsp->status = status;
			rsp->phase = phase;
			if (buf->len == 13) {
				rsp->ttl = net_buf_simple_pull_u8(buf);
				rsp->effect = net_buf_simple_pull_u8(buf) & BIT_MASK(5);
				rsp->timeout_base = net_buf_simple_pull_le16(buf);
				rsp->blob_id = net_buf_simple_pull_le64(buf);
				rsp->img_idx = net_buf_simple_pull_u8(buf);
			} else if (buf->len) {
				return -EINVAL;
			}

			rsp->ttl = 0U;
			rsp->effect = BT_MESH_DFU_EFFECT_NONE;
			rsp->timeout_base = 0U;
			rsp->blob_id = 0U;
			rsp->img_idx = 0U;
		}
		k_sem_give(&cli->req.sem);
	}
	if (cli->op != BT_MESH_DFU_OP_UPDATE_STATUS) {
		return 0;
	}

	target = target_get(cli, ctx->addr);
	if (!target) {
		LOG_WRN("Unknown target 0x%04x", ctx->addr);
		return -ENOENT;
	}

	LOG_DBG("%u phase: %u, cur state: %u", status, phase, cli->xfer.state);

	target->phase = phase;

	if (cli->xfer.state == STATE_APPLY && phase == BT_MESH_DFU_PHASE_IDLE &&
	    status == BT_MESH_DFU_ERR_WRONG_PHASE) {
		LOG_DBG("Response received with Idle phase");
		blob_cli_broadcast_rsp(&cli->blob, &target->blob);
		return 0;
	}

	if (status != BT_MESH_DFU_SUCCESS) {
		target_failed(cli, target, status);
		blob_cli_broadcast_rsp(&cli->blob, &target->blob);
		return 0;
	}

	if (buf->len == 13) {
		net_buf_simple_pull_u8(buf); /* ttl */
		target->effect = net_buf_simple_pull_u8(buf) & BIT_MASK(5);
		net_buf_simple_pull_le16(buf); /* timeout */

		if (net_buf_simple_pull_le64(buf) != cli->xfer.blob.id) {
			LOG_WRN("Invalid BLOB ID");
			target_failed(cli, target, BT_MESH_DFU_ERR_BLOB_XFER_BUSY);
			blob_cli_broadcast_rsp(&cli->blob, &target->blob);
			return 0;
		}

		target->img_idx = net_buf_simple_pull_u8(buf);

		LOG_DBG("Target 0x%04x receiving transfer", ctx->addr);
	} else if (buf->len) {
		return -EINVAL;
	}

	if (cli->xfer.state == STATE_REFRESH) {
		if (phase == BT_MESH_DFU_PHASE_VERIFY) {
			LOG_DBG("Still pending...");
			return 0;
		} else if (phase == BT_MESH_DFU_PHASE_VERIFY_FAIL) {
			LOG_WRN("Verification failed on target 0x%04x",
				target->blob.addr);
			target_failed(cli, target, BT_MESH_DFU_ERR_WRONG_PHASE);
		}
	} else if (cli->xfer.state == STATE_APPLY) {
		if (phase != BT_MESH_DFU_PHASE_APPLYING &&
		    (target->effect == BT_MESH_DFU_EFFECT_UNPROV ||
		     phase != BT_MESH_DFU_PHASE_IDLE)) {
			LOG_WRN("Target 0x%04x in phase %u after apply",
				target->blob.addr, phase);
			target_failed(cli, target, BT_MESH_DFU_ERR_WRONG_PHASE);
			blob_cli_broadcast_rsp(&cli->blob, &target->blob);
			return 0;
		}
		return 0;
	} else if (cli->xfer.state == STATE_CONFIRM) {
		if (phase == BT_MESH_DFU_PHASE_APPLYING) {
			LOG_DBG("Still pending...");
			return 0;
		}

		if (phase != BT_MESH_DFU_PHASE_IDLE) {
			LOG_WRN("Target 0x%04x in phase %u after apply",
				target->blob.addr, phase);
			target->phase = BT_MESH_DFU_PHASE_APPLY_FAIL;
			target_failed(cli, target, BT_MESH_DFU_ERR_WRONG_PHASE);
			blob_cli_broadcast_rsp(&cli->blob, &target->blob);
			return 0;
		}
	} else if (cli->xfer.state == STATE_CANCEL) {
		target->phase = BT_MESH_DFU_PHASE_TRANSFER_CANCELED;
	}

	blob_cli_broadcast_rsp(&cli->blob, &target->blob);

	return 0;
}

static int handle_info_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
			      struct net_buf_simple *buf)
{
	struct bt_mesh_dfu_cli *cli = mod->user_data;
	struct bt_mesh_dfu_target *target;
	enum bt_mesh_dfu_iter it = BT_MESH_DFU_ITER_CONTINUE;
	uint8_t img_cnt, idx;

	if (!cli->req.img_cb ||
	    (cli->req.type == REQ_IMG && cli->req.addr != ctx->addr)) {
		LOG_WRN("Unexpected info status from 0x%04x", ctx->addr);
		return 0;
	}

	img_cnt = net_buf_simple_pull_u8(buf);
	if (img_cnt < cli->req.img_cnt) {
		cli->req.img_cnt = img_cnt;
	}

	idx = net_buf_simple_pull_u8(buf);
	if (idx >= img_cnt) {
		LOG_WRN("Invalid idx %u", idx);
		return -ENOENT;
	}

	LOG_DBG("Image list from 0x%04x from index %u", ctx->addr, idx);

	while (buf->len && cli->req.img_cb && idx < cli->req.img_cnt) {
		char uri_buf[CONFIG_BT_MESH_DFU_URI_MAXLEN + 1];
		struct bt_mesh_dfu_img img;
		size_t uri_len;

		img.fwid_len = net_buf_simple_pull_u8(buf);
		if (buf->len < img.fwid_len + 1) {
			LOG_WRN("Invalid format: fwid");
			return -EINVAL;
		}

		img.fwid = net_buf_simple_pull_mem(buf, img.fwid_len);

		uri_len = net_buf_simple_pull_u8(buf);
		if (buf->len < uri_len) {
			LOG_WRN("Invalid format: uri");
			return -EINVAL;
		}

		LOG_DBG("\tImage %u\n\r\tfwid: %s", idx, bt_hex(img.fwid, img.fwid_len));

		if (uri_len) {
			size_t uri_buf_len =
				MIN(CONFIG_BT_MESH_DFU_URI_MAXLEN, uri_len);

			memcpy(uri_buf, net_buf_simple_pull_mem(buf, uri_len),
			       uri_buf_len);
			uri_buf[uri_buf_len] = '\0';
			img.uri = uri_buf;
		} else {
			img.uri = NULL;
		}

		it = cli->req.img_cb(cli, ctx, idx, img_cnt, &img,
				     cli->req.params);
		if (it != BT_MESH_DFU_ITER_CONTINUE) {
			if (cli->req.type == REQ_IMG) {
				k_sem_give(&cli->req.sem);
			}

			return 0;
		}

		idx++;
	}

	if (idx < cli->req.img_cnt) {
		LOG_DBG("Fetching more images (%u/%u)", idx, cli->req.img_cnt);
		ctx->send_ttl = cli->req.ttl;
		info_get(cli, ctx, idx, cli->req.img_cnt - idx,
			 (cli->req.type == REQ_IMG) ? NULL : &send_cb);
		return 0;
	}

	if (cli->req.type == REQ_IMG) {
		k_sem_give(&cli->req.sem);
		return 0;
	}

	/* Confirm-procedure termination: */
	target = target_get(cli, ctx->addr);
	if (target) {
		LOG_WRN("Target 0x%04x failed to apply image: %s", ctx->addr,
			bt_hex(cli->xfer.slot->fwid, cli->xfer.slot->fwid_len));
		target->phase = BT_MESH_DFU_PHASE_APPLY_FAIL;
		target_failed(cli, target, BT_MESH_DFU_ERR_INTERNAL);
		blob_cli_broadcast_rsp(&cli->blob, &target->blob);
	}

	return 0;
}

static int handle_metadata_status(struct bt_mesh_model *mod, struct bt_mesh_msg_ctx *ctx,
				  struct net_buf_simple *buf)
{
	struct bt_mesh_dfu_cli *cli = mod->user_data;
	struct bt_mesh_dfu_metadata_status *rsp = cli->req.params;
	uint8_t hdr, idx;

	hdr = net_buf_simple_pull_u8(buf);
	idx = net_buf_simple_pull_u8(buf);

	if (cli->req.type != REQ_METADATA || ctx->addr != cli->req.addr ||
	    idx != rsp->idx) {
		LOG_WRN("Unexpected metadata status from 0x%04x img %u",
			ctx->addr, idx);
		if (cli->req.type != REQ_METADATA) {
			LOG_WRN("Expected %u", cli->req.type);
		} else {
			LOG_WRN("Expected 0x%04x img %u", cli->req.addr, idx);
		}

		return 0;
	}

	rsp->status = hdr & BIT_MASK(3);
	rsp->effect = (hdr >> 3);
	k_sem_give(&cli->req.sem);

	return 0;
}

const struct bt_mesh_model_op _bt_mesh_dfu_cli_op[] = {
	{BT_MESH_DFU_OP_UPDATE_STATUS, BT_MESH_LEN_MIN(1), handle_status},
	{BT_MESH_DFU_OP_UPDATE_INFO_STATUS, BT_MESH_LEN_MIN(2), handle_info_status},
	{BT_MESH_DFU_OP_UPDATE_METADATA_STATUS, BT_MESH_LEN_EXACT(2), handle_metadata_status},
	BT_MESH_MODEL_OP_END,
};

static int dfu_cli_init(struct bt_mesh_model *mod)
{
	struct bt_mesh_dfu_cli *cli = mod->user_data;

	if (mod->elem_idx != 0) {
		LOG_ERR("DFU update client must be instantiated on first elem");
		return -EINVAL;
	}

	cli->mod = mod;

	if (IS_ENABLED(CONFIG_BT_MESH_MODEL_EXTENSIONS)) {
		bt_mesh_model_extend(mod, cli->blob.mod);
	}

	k_sem_init(&cli->req.sem, 0, 1);

	return 0;
}

static void dfu_cli_reset(struct bt_mesh_model *mod)
{
	struct bt_mesh_dfu_cli *cli = mod->user_data;

	cli->req.type = REQ_NONE;
	cli->req.addr = BT_MESH_ADDR_UNASSIGNED;
	cli->req.img_cnt = 0;
	cli->req.img_cb = NULL;
	cli->xfer.state = STATE_IDLE;
	cli->xfer.flags = 0;
}

const struct bt_mesh_model_cb _bt_mesh_dfu_cli_cb = {
	.init = dfu_cli_init,
	.reset = dfu_cli_reset,
};

/*******************************************************************************
 * Public API
 ******************************************************************************/

int bt_mesh_dfu_cli_send(struct bt_mesh_dfu_cli *cli,
			 const struct bt_mesh_blob_cli_inputs *inputs,
			 const struct bt_mesh_blob_io *io,
			 const struct bt_mesh_dfu_cli_xfer *xfer)
{
	struct bt_mesh_dfu_target *target;

	if (bt_mesh_dfu_cli_is_busy(cli)) {
		return -EBUSY;
	}

	cli->xfer.blob.mode = xfer->mode;
	cli->xfer.blob.size = xfer->slot->size;

	if (xfer->blob_id == 0) {
		sys_rand_get(&cli->xfer.blob.id, sizeof(cli->xfer.blob.id));
	} else {
		cli->xfer.blob.id = xfer->blob_id;
	}

	cli->xfer.io = io;
	cli->blob.inputs = inputs;
	cli->xfer.slot = xfer->slot;
	cli->xfer.flags = 0U;

	if (xfer->blob_params) {
		cli->xfer.flags |= FLAG_SKIP_CAPS_GET;
		cli->xfer.blob.block_size_log = xfer->blob_params->block_size_log;
		cli->xfer.blob.chunk_size = xfer->blob_params->chunk_size;
	}

	/* Phase will be set based on target status messages: */
	TARGETS_FOR_EACH(cli, target) {
		target->status = BT_MESH_DFU_SUCCESS;
		target->phase = BT_MESH_DFU_PHASE_UNKNOWN;
	}

	initiate(cli);
	return 0;
}

int bt_mesh_dfu_cli_suspend(struct bt_mesh_dfu_cli *cli)
{
	int err;

	err = bt_mesh_blob_cli_suspend(&cli->blob);
	if (!err) {
		cli->xfer.state = STATE_SUSPENDED;
	}

	return err;
}

int bt_mesh_dfu_cli_resume(struct bt_mesh_dfu_cli *cli)
{
	struct bt_mesh_dfu_target *target;

	if (cli->xfer.state != STATE_SUSPENDED) {
		return -EINVAL;
	}

	cli->xfer.flags = FLAG_RESUME;

	/* Restore timed out targets. */
	TARGETS_FOR_EACH(cli, target) {
		if (!!target->blob.timedout) {
			target->status = BT_MESH_DFU_SUCCESS;
			target->phase = BT_MESH_DFU_PHASE_UNKNOWN;
		}
	}

	initiate(cli);
	return 0;
}

int bt_mesh_dfu_cli_cancel(struct bt_mesh_dfu_cli *cli,
			   struct bt_mesh_msg_ctx *ctx)
{
	if (ctx) {
		int err;

		err = req_setup(cli, REQ_STATUS, ctx->addr, NULL);
		if (err) {
			return err;
		}

		BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_CANCEL, 0);
		bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_CANCEL);

		err = bt_mesh_model_send(cli->mod, ctx, &buf, NULL, NULL);
		if (err) {
			cli->req.type = REQ_NONE;
			return err;
		}

		return req_wait(cli, K_MSEC(dfu_cli_timeout));
	}

	if (cli->xfer.state == STATE_IDLE) {
		return -EALREADY;
	}

	cli->xfer.state = STATE_CANCEL;
	blob_cli_broadcast_abort(&cli->blob);
	cancel(cli);
	return 0;
}

int bt_mesh_dfu_cli_apply(struct bt_mesh_dfu_cli *cli)
{
	if (cli->xfer.state != STATE_VERIFIED) {
		return -EBUSY;
	}

	apply(cli);

	return 0;
}

int bt_mesh_dfu_cli_confirm(struct bt_mesh_dfu_cli *cli)
{
	if (cli->xfer.state != STATE_APPLIED) {
		return -EBUSY;
	}

	cli->xfer.state = STATE_CONFIRM;
	confirm(cli);

	return 0;
}

uint8_t bt_mesh_dfu_cli_progress(struct bt_mesh_dfu_cli *cli)
{
	if (cli->xfer.state == STATE_TRANSFER) {
		return bt_mesh_blob_cli_xfer_progress_active_get(&cli->blob);
	}

	if (cli->xfer.state == STATE_IDLE) {
		if (cli->xfer.flags & FLAG_COMPLETED) {
			return 100U;
		}
		return 0U;
	}

	return 100U;
}

bool bt_mesh_dfu_cli_is_busy(struct bt_mesh_dfu_cli *cli)
{
	return (cli->xfer.state == STATE_TRANSFER ||
		cli->xfer.state == STATE_REFRESH ||
		cli->xfer.state == STATE_APPLY ||
		cli->xfer.state == STATE_CONFIRM) &&
	       !(cli->xfer.flags & FLAG_FAILED);
}

int bt_mesh_dfu_cli_imgs_get(struct bt_mesh_dfu_cli *cli,
			     struct bt_mesh_msg_ctx *ctx,
			     bt_mesh_dfu_img_cb_t cb, void *cb_data,
			     uint8_t max_count)
{
	int err;

	if (cli->req.img_cb) {
		return -EBUSY;
	}

	err = req_setup(cli, REQ_IMG, ctx->addr, NULL);
	if (err) {
		return err;
	}

	cli->req.img_cb = cb;
	cli->req.params = cb_data;
	cli->req.ttl = ctx->send_ttl;
	cli->req.img_cnt = max_count;

	err = info_get(cli, ctx, 0, cli->req.img_cnt,  NULL);
	if (err) {
		cli->req.img_cb = NULL;
		cli->req.type = REQ_NONE;
		return err;
	}

	err = req_wait(cli, K_MSEC(dfu_cli_timeout));

	cli->req.img_cb = NULL;

	return err;
}

int bt_mesh_dfu_cli_metadata_check(struct bt_mesh_dfu_cli *cli,
				   struct bt_mesh_msg_ctx *ctx, uint8_t img_idx,
				   const struct bt_mesh_dfu_slot *slot,
				   struct bt_mesh_dfu_metadata_status *rsp)
{
	int err;

	err = req_setup(cli, REQ_METADATA, ctx->addr, rsp);
	if (err) {
		return err;
	}

	BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_METADATA_CHECK,
				 1 + CONFIG_BT_MESH_DFU_METADATA_MAXLEN);
	bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_METADATA_CHECK);

	net_buf_simple_add_u8(&buf, img_idx);

	if (slot->metadata_len) {
		net_buf_simple_add_mem(&buf, slot->metadata,
				       slot->metadata_len);
	}

	rsp->idx = img_idx;

	err = bt_mesh_model_send(cli->mod, ctx, &buf, NULL, NULL);
	if (err) {
		cli->req.type = REQ_NONE;
		return err;
	}

	return req_wait(cli, K_MSEC(dfu_cli_timeout));
}

int bt_mesh_dfu_cli_status_get(struct bt_mesh_dfu_cli *cli,
			       struct bt_mesh_msg_ctx *ctx,
			       struct bt_mesh_dfu_target_status *rsp)
{
	int err;

	err = req_setup(cli, REQ_STATUS, ctx->addr, rsp);
	if (err) {
		return err;
	}

	BT_MESH_MODEL_BUF_DEFINE(buf, BT_MESH_DFU_OP_UPDATE_GET, 0);
	bt_mesh_model_msg_init(&buf, BT_MESH_DFU_OP_UPDATE_GET);

	err = bt_mesh_model_send(cli->mod, ctx, &buf, NULL, NULL);
	if (err) {
		cli->req.type = REQ_NONE;
		return err;
	}

	return req_wait(cli, K_MSEC(dfu_cli_timeout));
}

int32_t bt_mesh_dfu_cli_timeout_get(void)
{
	return dfu_cli_timeout;
}

void bt_mesh_dfu_cli_timeout_set(int32_t t)
{
	dfu_cli_timeout = t;
}
