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

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zcbor_common.h>
#include <zcbor_decode.h>
#include <zcbor_encode.h>

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/net/buf.h>
#include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
#include <zephyr/mgmt/mcumgr/smp/smp.h>
#include <zephyr/mgmt/mcumgr/smp/smp_client.h>
#include <zephyr/mgmt/mcumgr/transport/smp.h>
#include <zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h>
#include <zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h>

#include <mgmt/mcumgr/util/zcbor_bulk.h>
#include <mgmt/mcumgr/transport/smp_internal.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(mcumgr_grp_img_client, CONFIG_MCUMGR_GRP_IMG_CLIENT_LOG_LEVEL);

#define MCUMGR_UPLOAD_INIT_HEADER_BUF_SIZE 128

/* Pointer for active Client */
static struct img_mgmt_client *active_client;
/* Image State read or set response pointer */
static struct mcumgr_image_state *image_info;
/* Image upload response pointer */
static struct mcumgr_image_upload *image_upload_buf;

static K_SEM_DEFINE(mcumgr_img_client_grp_sem, 0, 1);
static K_MUTEX_DEFINE(mcumgr_img_client_grp_mutex);

static const char smp_images_str[] = "images";
#define IMAGES_STR_LEN (sizeof(smp_images_str) - 1)

static int image_state_res_fn(struct net_buf *nb, void *user_data)
{
	zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2];
	struct zcbor_string value = {0};
	int buf_len, rc;
	uint32_t img_num, slot_num;
	struct zcbor_string hash, version;
	bool bootable, pending, confirmed, active, permanent, ok;
	size_t decoded;
	struct zcbor_map_decode_key_val list_res_decode[] = {
		/* Mandatory */
		ZCBOR_MAP_DECODE_KEY_DECODER("version", zcbor_tstr_decode, &version),
		ZCBOR_MAP_DECODE_KEY_DECODER("hash", zcbor_bstr_decode, &hash),
		ZCBOR_MAP_DECODE_KEY_DECODER("slot", zcbor_uint32_decode, &slot_num),
		/* Optional */
		ZCBOR_MAP_DECODE_KEY_DECODER("image", zcbor_uint32_decode, &img_num),
		ZCBOR_MAP_DECODE_KEY_DECODER("bootable", zcbor_bool_decode, &bootable),
		ZCBOR_MAP_DECODE_KEY_DECODER("pending", zcbor_bool_decode, &pending),
		ZCBOR_MAP_DECODE_KEY_DECODER("confirmed", zcbor_bool_decode, &confirmed),
		ZCBOR_MAP_DECODE_KEY_DECODER("active", zcbor_bool_decode, &active),
		ZCBOR_MAP_DECODE_KEY_DECODER("permanent", zcbor_bool_decode, &permanent)
		};

	buf_len = active_client->image_list_length;

	if (!nb) {
		image_info->status = MGMT_ERR_ETIMEOUT;
		goto out;
	}

	zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1);

	ok = zcbor_map_start_decode(zsd);
	if (!ok) {
		image_info->status = MGMT_ERR_ECORRUPT;
		goto out;
	}

	ok = zcbor_tstr_decode(zsd, &value);
	if (!ok) {
		image_info->status = MGMT_ERR_ECORRUPT;
		goto out;
	}
	if (value.len != IMAGES_STR_LEN || memcmp(value.value, smp_images_str, IMAGES_STR_LEN)) {
		image_info->status = MGMT_ERR_EINVAL;
		goto out;
	}

	ok = zcbor_list_start_decode(zsd);
	if (!ok) {
		image_info->status = MGMT_ERR_ECORRUPT;
		goto out;
	}

	rc = 0;
	/* Parse Image map info to configured buffer */
	while (rc == 0) {
		decoded = 0;
		zcbor_map_decode_bulk_reset(list_res_decode, ARRAY_SIZE(list_res_decode));
		/* Init buffer values */
		active = false;
		bootable = false;
		confirmed = false;
		pending = false;
		permanent = false;
		img_num = 0;
		slot_num = UINT32_MAX;
		hash.len = 0;
		version.len = 0;

		rc = zcbor_map_decode_bulk(zsd, list_res_decode, ARRAY_SIZE(list_res_decode),
					   &decoded);
		if (rc) {
			if (image_info->image_list_length) {
				/* No more map */
				break;
			}
			LOG_ERR("Corrupted Image data %d", rc);
			image_info->status = MGMT_ERR_EINVAL;
			goto out;
		}
		/* Check that mandatory parameters have decoded */
		if (hash.len != IMG_MGMT_DATA_SHA_LEN || !version.len ||
		    !zcbor_map_decode_bulk_key_found(list_res_decode, ARRAY_SIZE(list_res_decode),
						     "slot")) {
			LOG_ERR("Missing mandatory parametrs");
			image_info->status = MGMT_ERR_EINVAL;
			goto out;
		}
		/* Store parsed values */
		if (buf_len) {
			image_info->image_list[image_info->image_list_length].img_num = img_num;
			image_info->image_list[image_info->image_list_length].slot_num = slot_num;
			memcpy(image_info->image_list[image_info->image_list_length].hash,
			       hash.value, IMG_MGMT_DATA_SHA_LEN);
			if (version.len > IMG_MGMT_VER_MAX_STR_LEN) {
				LOG_WRN("Version truncated len %d -> %d", version.len,
					IMG_MGMT_VER_MAX_STR_LEN);
				version.len = IMG_MGMT_VER_MAX_STR_LEN;
			}
			memcpy(image_info->image_list[image_info->image_list_length].version,
			       version.value, version.len);
			image_info->image_list[image_info->image_list_length].version[version.len] =
				'\0';
			/* Set Image flags */
			image_info->image_list[image_info->image_list_length].flags.bootable =
				bootable;
			image_info->image_list[image_info->image_list_length].flags.pending =
				pending;
			image_info->image_list[image_info->image_list_length].flags.confirmed =
				confirmed;
			image_info->image_list[image_info->image_list_length].flags.active = active;
			image_info->image_list[image_info->image_list_length].flags.permanent =
				permanent;
			/* Update valid image count */
			image_info->image_list_length++;
			buf_len--;
		} else {
			LOG_INF("User configured image list buffer size %d can't store all info",
				active_client->image_list_length);
		}
	}

	ok = zcbor_list_end_decode(zsd);
	if (!ok) {
		image_info->status = MGMT_ERR_ECORRUPT;
	} else {

		image_info->status = MGMT_ERR_EOK;
	}

out:
	if (image_info->status != MGMT_ERR_EOK) {
		image_info->image_list_length = 0;
	}
	rc = image_info->status;
	k_sem_give(user_data);
	return rc;
}

static int image_upload_res_fn(struct net_buf *nb, void *user_data)
{
	zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2];
	size_t decoded;
	int rc;
	int32_t res_rc = MGMT_ERR_EOK;

	struct zcbor_map_decode_key_val upload_res_decode[] = {
		ZCBOR_MAP_DECODE_KEY_DECODER("off", zcbor_size_decode,
					     &image_upload_buf->image_upload_offset),
		ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &res_rc)};

	if (!nb) {
		image_upload_buf->status = MGMT_ERR_ETIMEOUT;
		goto end;
	}

	zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1);

	rc = zcbor_map_decode_bulk(zsd, upload_res_decode, ARRAY_SIZE(upload_res_decode), &decoded);
	if (rc || image_upload_buf->image_upload_offset == SIZE_MAX) {
		image_upload_buf->status = MGMT_ERR_EINVAL;
		goto end;
	}
	image_upload_buf->status = res_rc;

	active_client->upload.offset = image_upload_buf->image_upload_offset;
end:
	/* Set status for Upload request handler */
	rc = image_upload_buf->status;
	k_sem_give(user_data);
	return rc;
}

static int erase_res_fn(struct net_buf *nb, void *user_data)
{
	zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2];
	size_t decoded;
	int rc, status = MGMT_ERR_EOK;

	struct zcbor_map_decode_key_val upload_res_decode[] = {
		ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &status)
		};

	if (!nb) {
		active_client->status = MGMT_ERR_ETIMEOUT;
		goto end;
	}

	zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1);

	rc = zcbor_map_decode_bulk(zsd, upload_res_decode, ARRAY_SIZE(upload_res_decode), &decoded);
	if (rc) {
		LOG_ERR("Erase fail %d", rc);
		active_client->status = MGMT_ERR_EINVAL;
		goto end;
	}
	active_client->status = status;
end:
	rc = active_client->status;
	k_sem_give(user_data);
	return rc;
}

static size_t upload_message_header_size(struct img_gr_upload *upload_state)
{
	bool ok;
	size_t cbor_length;
	int map_count;
	zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2];
	uint8_t temp_buf[MCUMGR_UPLOAD_INIT_HEADER_BUF_SIZE];
	uint8_t temp_data;

	/* Calculation of message header with data length of 1 */

	zcbor_new_encode_state(zse, ARRAY_SIZE(zse), temp_buf, MCUMGR_UPLOAD_INIT_HEADER_BUF_SIZE,
			       0);
	if (upload_state->hash_initialized) {
		map_count = 12;
	} else {
		map_count = 10;
	}

	/* Init map start and write image info and data */
	ok = zcbor_map_start_encode(zse, map_count) && zcbor_tstr_put_lit(zse, "image") &&
	     zcbor_uint32_put(zse, upload_state->image_num) && zcbor_tstr_put_lit(zse, "data") &&
	     zcbor_bstr_encode_ptr(zse, &temp_data, 1) && zcbor_tstr_put_lit(zse, "len") &&
	     zcbor_size_put(zse, upload_state->image_size) && zcbor_tstr_put_lit(zse, "off") &&
	     zcbor_size_put(zse, upload_state->offset);

	/* Write hash when it defined and offset is 0 */
	if (ok && upload_state->hash_initialized) {
		ok = zcbor_tstr_put_lit(zse, "sha") &&
		     zcbor_bstr_encode_ptr(zse, upload_state->sha256, IMG_MGMT_DATA_SHA_LEN);
	}

	if (ok) {
		ok = zcbor_map_end_encode(zse, map_count);
	}

	if (!ok) {
		LOG_ERR("Failed to encode Image Upload packet");
		return 0;
	}
	cbor_length = zse->payload - temp_buf;
	/* Return Message header length */
	return cbor_length + (CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE - 1);
}

void img_mgmt_client_init(struct img_mgmt_client *client, struct smp_client_object *smp_client,
			  int image_list_size, struct mcumgr_image_data *image_list)
{
	client->smp_client = smp_client;
	client->image_list_length = image_list_size;
	client->image_list = image_list;
}

int img_mgmt_client_upload_init(struct img_mgmt_client *client, size_t image_size,
				uint32_t image_num, const char *image_hash)
{
	int rc;

	k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER);
	client->upload.image_size = image_size;
	client->upload.offset = 0;
	client->upload.image_num = image_num;
	if (image_hash) {
		memcpy(client->upload.sha256, image_hash, IMG_MGMT_DATA_SHA_LEN);
		client->upload.hash_initialized = true;
	} else {
		client->upload.hash_initialized = false;
	}

	/* Calculate worst case header size for adapt payload length */
	client->upload.upload_header_size = upload_message_header_size(&client->upload);
	if (client->upload.upload_header_size) {
		rc = MGMT_ERR_EOK;
	} else {
		rc = MGMT_ERR_ENOMEM;
	}
	k_mutex_unlock(&mcumgr_img_client_grp_mutex);
	return rc;
}

int img_mgmt_client_upload(struct img_mgmt_client *client, const uint8_t *data, size_t length,
			   struct mcumgr_image_upload *res_buf)
{
	struct net_buf *nb;
	const uint8_t *write_ptr;
	int rc;
	uint32_t map_count;
	bool ok;
	size_t write_length, max_data_length, offset_before_send, request_length, wrote_length;
	zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2];

	k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER);
	active_client = client;
	image_upload_buf = res_buf;

	request_length = length;
	wrote_length = 0;
	/* Calculate max data length based on
	 * net_buf size - (SMP header + CBOR message_len + 16-bit CRC + 16-bit length)
	 */
	max_data_length = CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE -
			  (active_client->upload.upload_header_size + MGMT_HDR_SIZE + 2U + 2U);
	/* Trim length based on CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE */
	if (max_data_length % CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE) {
		max_data_length -=
			(max_data_length % CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE);
	}

	while (request_length != wrote_length) {
		write_ptr = data + wrote_length;
		write_length = request_length - wrote_length;
		if (write_length > max_data_length) {
			write_length = max_data_length;
		}

		nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE,
					       IMG_MGMT_ID_UPLOAD, MGMT_OP_WRITE,
					       SMP_MCUMGR_VERSION_1);
		if (!nb) {
			image_upload_buf->status = MGMT_ERR_ENOMEM;
			goto end;
		}

		zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len,
				       net_buf_tailroom(nb), 0);
		if (active_client->upload.offset) {
			map_count = 6;
		} else if (active_client->upload.hash_initialized) {
			map_count = 12;
		} else {
			map_count = 10;
		}

		/* Init map start and write image info, data and offset */
		ok = zcbor_map_start_encode(zse, map_count) && zcbor_tstr_put_lit(zse, "image") &&
		     zcbor_uint32_put(zse, active_client->upload.image_num) &&
		     zcbor_tstr_put_lit(zse, "data") &&
		     zcbor_bstr_encode_ptr(zse, write_ptr, write_length) &&
		     zcbor_tstr_put_lit(zse, "off") &&
		     zcbor_size_put(zse, active_client->upload.offset);
		/* Write Len and configured hash when offset is zero */
		if (ok && !active_client->upload.offset) {
			ok = zcbor_tstr_put_lit(zse, "len") &&
			     zcbor_size_put(zse, active_client->upload.image_size);
			if (ok && active_client->upload.hash_initialized) {
				ok = zcbor_tstr_put_lit(zse, "sha") &&
				     zcbor_bstr_encode_ptr(zse, active_client->upload.sha256,
							   IMG_MGMT_DATA_SHA_LEN);
			}
		}

		if (ok) {
			ok = zcbor_map_end_encode(zse, map_count);
		}

		if (!ok) {
			LOG_ERR("Failed to encode Image Upload packet");
			smp_packet_free(nb);
			image_upload_buf->status = MGMT_ERR_ENOMEM;
			goto end;
		}

		offset_before_send = active_client->upload.offset;
		nb->len = zse->payload - nb->data;
		k_sem_reset(&mcumgr_img_client_grp_sem);

		image_upload_buf->status = MGMT_ERR_EINVAL;
		image_upload_buf->image_upload_offset = SIZE_MAX;

		rc = smp_client_send_cmd(active_client->smp_client, nb, image_upload_res_fn,
					 &mcumgr_img_client_grp_sem,
					 CONFIG_MCUMGR_GRP_IMG_FLASH_OPERATION_TIMEOUT);
		if (rc) {
			LOG_ERR("Failed to send SMP Upload init packet, err: %d", rc);
			smp_packet_free(nb);
			image_upload_buf->status = rc;
			goto end;

		}
		k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER);
		if (image_upload_buf->status) {
			LOG_ERR("Upload Fail: %d", image_upload_buf->status);
			goto end;
		}

		if (offset_before_send + write_length < active_client->upload.offset) {
			/* Offset further than expected which indicate upload session resume */
			goto end;
		}

		wrote_length += write_length;
	}
end:
	rc = image_upload_buf->status;
	active_client = NULL;
	image_upload_buf = NULL;
	k_mutex_unlock(&mcumgr_img_client_grp_mutex);

	return rc;
}

int img_mgmt_client_state_write(struct img_mgmt_client *client, char *hash, bool confirm,
				struct mcumgr_image_state *res_buf)
{
	struct net_buf *nb;
	int rc;
	uint32_t map_count;
	zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS];
	bool ok;

	k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER);
	active_client = client;
	image_info = res_buf;
	/* Init Response */
	res_buf->image_list_length = 0;
	res_buf->image_list = active_client->image_list;

	nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE,
				       IMG_MGMT_ID_STATE, MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1);
	if (!nb) {
		res_buf->status = MGMT_ERR_ENOMEM;
		goto end;
	}

	zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0);
	if (hash) {
		map_count = 4;
	} else {
		map_count = 2;
	}

	/* Write map start init and confirm params */
	ok = zcbor_map_start_encode(zse, map_count) && zcbor_tstr_put_lit(zse, "confirm") &&
	     zcbor_bool_put(zse, confirm);
	/* Write hash data */
	if (ok && hash) {
		ok = zcbor_tstr_put_lit(zse, "hash") &&
		     zcbor_bstr_encode_ptr(zse, hash, IMG_MGMT_DATA_SHA_LEN);
	}
	/* Close map */
	if (ok) {
		ok = zcbor_map_end_encode(zse, map_count);
	}

	if (!ok) {
		smp_packet_free(nb);
		res_buf->status = MGMT_ERR_ENOMEM;
		goto end;
	}

	nb->len = zse->payload - nb->data;
	k_sem_reset(&mcumgr_img_client_grp_sem);
	rc = smp_client_send_cmd(active_client->smp_client, nb, image_state_res_fn,
				 &mcumgr_img_client_grp_sem, CONFIG_SMP_CMD_DEFAULT_LIFE_TIME);
	if (rc) {
		res_buf->status = rc;
		smp_packet_free(nb);
		goto end;
	}
	k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER);
end:
	rc = res_buf->status;
	active_client = NULL;
	k_mutex_unlock(&mcumgr_img_client_grp_mutex);
	return rc;
}

int img_mgmt_client_state_read(struct img_mgmt_client *client, struct mcumgr_image_state *res_buf)
{
	struct net_buf *nb;
	int rc;
	zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS];
	bool ok;

	k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER);
	active_client = client;
	/* Init Response */
	res_buf->image_list_length = 0;
	res_buf->image_list = active_client->image_list;

	image_info = res_buf;

	nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE,
				       IMG_MGMT_ID_STATE, MGMT_OP_READ, SMP_MCUMGR_VERSION_1);
	if (!nb) {
		res_buf->status = MGMT_ERR_ENOMEM;
		goto end;
	}

	zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0);
	ok = zcbor_map_start_encode(zse, 1) && zcbor_map_end_encode(zse, 1);
	if (!ok) {
		smp_packet_free(nb);
		res_buf->status = MGMT_ERR_ENOMEM;
		goto end;
	}

	nb->len = zse->payload - nb->data;
	k_sem_reset(&mcumgr_img_client_grp_sem);
	rc = smp_client_send_cmd(active_client->smp_client, nb, image_state_res_fn,
				 &mcumgr_img_client_grp_sem, CONFIG_SMP_CMD_DEFAULT_LIFE_TIME);
	if (rc) {
		smp_packet_free(nb);
		res_buf->status = rc;
		goto end;
	}
	k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER);
end:
	rc = res_buf->status;
	image_info = NULL;
	active_client = NULL;
	k_mutex_unlock(&mcumgr_img_client_grp_mutex);
	return rc;
}

int img_mgmt_client_erase(struct img_mgmt_client *client, uint32_t slot)
{
	struct net_buf *nb;
	int rc;
	zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS];
	bool ok;

	k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER);
	active_client = client;

	nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE,
				       IMG_MGMT_ID_ERASE, MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1);
	if (!nb) {
		active_client->status = MGMT_ERR_ENOMEM;
		goto end;
	}

	zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0);

	ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "slot") &&
	     zcbor_uint32_put(zse, slot) && zcbor_map_end_encode(zse, 2);
	if (!ok) {
		smp_packet_free(nb);
		active_client->status = MGMT_ERR_ENOMEM;
		goto end;
	}

	nb->len = zse->payload - nb->data;
	k_sem_reset(&mcumgr_img_client_grp_sem);
	rc = smp_client_send_cmd(client->smp_client, nb, erase_res_fn, &mcumgr_img_client_grp_sem,
				 CONFIG_MCUMGR_GRP_IMG_FLASH_OPERATION_TIMEOUT);
	if (rc) {
		smp_packet_free(nb);
		active_client->status = rc;
		goto end;
	}
	k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER);
end:
	rc = active_client->status;
	active_client = NULL;
	k_mutex_unlock(&mcumgr_img_client_grp_mutex);
	return rc;
}
