/*
 * 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/rand32.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 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(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(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(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(timeout));
}

int32_t bt_mesh_dfu_cli_timeout_get(void)
{
	return timeout;
}

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