/*
 * Copyright (c) 2018-2021 mcumgr authors
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(mcumgr_img_mgmt, CONFIG_MCUMGR_IMG_MGMT_LOG_LEVEL);

#include <zephyr/kernel.h>
#include <zephyr/init.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/storage/flash_map.h>
#include <zephyr/dfu/mcuboot.h>
#include <zephyr/dfu/flash_img.h>
#include <bootutil/bootutil_public.h>
#include <assert.h>

#include <zephyr/mgmt/mcumgr/mgmt/mgmt.h>
#include <zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h>
#include <zephyr/mgmt/mcumgr/grp/img_mgmt/image.h>

#include <mgmt/mcumgr/grp/img_mgmt/img_mgmt_impl.h>
#include <mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h>

#define SLOT0_PARTITION		slot0_partition
#define SLOT1_PARTITION		slot1_partition
#define SLOT2_PARTITION		slot2_partition
#define SLOT3_PARTITION		slot3_partition

BUILD_ASSERT(CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 1 ||
	     (CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 2 &&
	      FIXED_PARTITION_EXISTS(SLOT2_PARTITION) &&
	      FIXED_PARTITION_EXISTS(SLOT3_PARTITION)),
	     "Missing partitions?");

static int
img_mgmt_slot_to_image(int slot)
{
	switch (slot) {
	case 0:
	case 1:
		return 0;
#if FIXED_PARTITION_EXISTS(SLOT2_PARTITION) && FIXED_PARTITION_EXISTS(SLOT2_PARTITION)
	case 2:
	case 3:
		return 1;
#endif
	default:
		assert(0);
	}
	return 0;
}

/**
 * Determines if the specified area of flash is completely unwritten.
 *
 * @param	fa	pointer to flash area to scan
 *
 * @return	0 when not empty, 1 when empty, negative errno code on error.
 */
static int img_mgmt_flash_check_empty_inner(const struct flash_area *fa)
{
	uint32_t data[16];
	off_t addr;
	off_t end;
	int bytes_to_read;
	int rc;
	int i;
	uint8_t erased_val;
	uint32_t erased_val_32;

	assert(fa->fa_size % 4 == 0);

	erased_val = flash_area_erased_val(fa);
	erased_val_32 = ERASED_VAL_32(erased_val);

	end = fa->fa_size;
	for (addr = 0; addr < end; addr += sizeof(data)) {
		if (end - addr < sizeof(data)) {
			bytes_to_read = end - addr;
		} else {
			bytes_to_read = sizeof(data);
		}

		rc = flash_area_read(fa, addr, data, bytes_to_read);
		if (rc < 0) {
			return rc;
		}

		for (i = 0; i < bytes_to_read / 4; i++) {
			if (data[i] != erased_val_32) {
				return 0;
			}
		}
	}

	return 1;
}

#ifndef CONFIG_IMG_ERASE_PROGRESSIVELY
/* Check if area is empty
 *
 * @param	fa_id	ID of flash area to scan.
 *
 * @return	0 when not empty, 1 when empty, negative errno code on error.
 */
static int img_mgmt_flash_check_empty(uint8_t fa_id)
{
	const struct flash_area *fa;
	int rc;

	rc = flash_area_open(fa_id, &fa);
	if (rc == 0) {
		rc = img_mgmt_flash_check_empty_inner(fa);

		flash_area_close(fa);
	}

	return rc;
}
#endif

/**
 * Get flash_area ID for a image number; actually the slots are images
 * for Zephyr, as slot 0 of image 0 is image_0, slot 0 of image 1 is
 * image_2 and so on. The function treats slot numbers as absolute
 * slot number starting at 0.
 */
static int
img_mgmt_flash_area_id(int slot)
{
	uint8_t fa_id;

	switch (slot) {
	case 0:
		fa_id = FIXED_PARTITION_ID(SLOT0_PARTITION);
		break;

	case 1:
		fa_id = FIXED_PARTITION_ID(SLOT1_PARTITION);
		break;

#if FIXED_PARTITION_EXISTS(SLOT2_PARTITION)
	case 2:
		fa_id = FIXED_PARTITION_ID(SLOT2_PARTITION);
		break;
#endif

#if FIXED_PARTITION_EXISTS(SLOT3_PARTITION)
	case 3:
		fa_id = FIXED_PARTITION_ID(SLOT3_PARTITION);
		break;
#endif

	default:
		fa_id = -1;
		break;
	}

	return fa_id;
}

#if CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 1
/**
 * In normal operation this function will select between first two slot
 * (in reality it just checks whether second slot can be used), ignoring the
 * slot parameter.
 * When CONFIG_IMG_MGMT_DIRECT_IMAGE_UPLOAD is defined it will check if given
 * slot is available, and allowed, for DFU; providing 0 as a parameter means
 * find any unused and non-active available (auto-select); any other positive
 * value is direct (slot + 1) to be used; if checks are positive, then area
 * ID is returned, -1 is returned otherwise.
 * Note that auto-selection is performed only between two two first slots.
 */
static int
img_mgmt_get_unused_slot_area_id(int slot)
{
#if defined(CONFIG_IMG_MGMT_DIRECT_IMAGE_UPLOAD)
	slot--;
	if (slot < -1) {
		return -1;
	} else if (slot == -1) {
#endif
		/*
		 * Auto select slot; note that this is performed only between two first
		 * slots, at this point, which will require fix when Direct-XIP, which
		 * may support more slots, gets support within Zephyr.
		 */
		for (slot = 0; slot < 2; slot++) {
			if (img_mgmt_slot_in_use(slot) == 0) {
				int area_id = img_mgmt_flash_area_id(slot);

				if (area_id >= 0) {
					return area_id;
				}
			}
		}
		return -1;
#if defined(CONFIG_IMG_MGMT_DIRECT_IMAGE_UPLOAD)
	}
	/*
	 * Direct selection; the first two slots are checked for being available
	 * and unused; the all other slots are just checked for availability.
	 */
	if (slot < 2) {
		slot = img_mgmt_slot_in_use(slot) == 0 ? slot : -1;
	}

	/* Return area ID for the slot or -1 */
	return slot != -1  ? img_mgmt_flash_area_id(slot) : -1;
#endif
}

#elif CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 2
static int
img_mgmt_get_unused_slot_area_id(int image)
{
	int area_id = -1;

	if (image == 0 || image == -1) {
		if (img_mgmt_slot_in_use(1) == 0) {
			area_id = img_mgmt_flash_area_id(1);
		}
	} else if (image == 1) {
		area_id = img_mgmt_flash_area_id(3);
	}

	return area_id;
}
#else
#error "Unsupported number of images"
#endif

int
img_mgmt_vercmp(const struct image_version *a, const struct image_version *b)
{
	if (a->iv_major < b->iv_major) {
		return -1;
	} else if (a->iv_major > b->iv_major) {
		return 1;
	}

	if (a->iv_minor < b->iv_minor) {
		return -1;
	} else if (a->iv_minor > b->iv_minor) {
		return 1;
	}

	if (a->iv_revision < b->iv_revision) {
		return -1;
	} else if (a->iv_revision > b->iv_revision) {
		return 1;
	}

	/* Note: For semver compatibility, don't compare the 32-bit build num. */

	return 0;
}

int
img_mgmt_erase_slot(int slot)
{
	const struct flash_area *fa;
	int rc;
	int area_id = img_mgmt_flash_area_id(slot);

	if (area_id < 0) {
		return MGMT_ERR_EUNKNOWN;
	}

	rc = flash_area_open(area_id, &fa);

	if (rc < 0) {
		return MGMT_ERR_EUNKNOWN;
	}

	rc = img_mgmt_flash_check_empty_inner(fa);

	if (rc == 0) {
		rc = flash_area_erase(fa, 0, fa->fa_size);
	}

	flash_area_close(fa);

	return (rc >= 0 ? MGMT_ERR_EOK : MGMT_ERR_EUNKNOWN);
}

int
img_mgmt_write_pending(int slot, bool permanent)
{
	int rc;

	if (slot != 1 && !(CONFIG_IMG_MGMT_UPDATABLE_IMAGE_NUMBER == 2 && slot == 3)) {
		return MGMT_ERR_EINVAL;
	}

	rc = boot_request_upgrade_multi(img_mgmt_slot_to_image(slot), permanent);
	if (rc != 0) {
		return MGMT_ERR_EUNKNOWN;
	}

	return 0;
}

int
img_mgmt_write_confirmed(void)
{
	int rc;

	rc = boot_write_img_confirmed();
	if (rc != 0) {
		return MGMT_ERR_EUNKNOWN;
	}

	return 0;
}

int
img_mgmt_read(int slot, unsigned int offset, void *dst, unsigned int num_bytes)
{
	const struct flash_area *fa;
	int rc;
	int area_id = img_mgmt_flash_area_id(slot);

	if (area_id < 0) {
		return MGMT_ERR_EUNKNOWN;
	}

	rc = flash_area_open(area_id, &fa);
	if (rc != 0) {
		return MGMT_ERR_EUNKNOWN;
	}

	rc = flash_area_read(fa, offset, dst, num_bytes);
	flash_area_close(fa);

	if (rc != 0) {
		return MGMT_ERR_EUNKNOWN;
	}

	return 0;
}

#if defined(CONFIG_IMG_MGMT_USE_HEAP_FOR_FLASH_IMG_CONTEXT)
int
img_mgmt_write_image_data(unsigned int offset, const void *data, unsigned int num_bytes, bool last)
{
	/* Even if CONFIG_HEAP_MEM_POOL_SIZE will be able to match size of the structure,
	 * keep in mind that when application will put the heap under pressure, obtaining
	 * of a flash image context may not be possible, so plan bigger heap size or
	 * make sure to limit application pressure on heap when DFU is expected.
	 */
	BUILD_ASSERT(CONFIG_HEAP_MEM_POOL_SIZE >= (sizeof(struct flash_img_context)),
		     "Not enough heap mem for flash_img_context.");

	int rc = MGMT_ERR_EOK;
	static struct flash_img_context *ctx;

	if (offset != 0 && ctx == NULL) {
		return MGMT_ERR_EUNKNOWN;
	}

	if (offset == 0) {
		if (ctx != NULL) {
			return MGMT_ERR_EUNKNOWN;
		}
		ctx = k_malloc(sizeof(struct flash_img_context));

		if (ctx == NULL) {
			return MGMT_ERR_ENOMEM;
		}

		if (flash_img_init_id(ctx, g_img_mgmt_state.area_id) != 0) {
			rc = MGMT_ERR_EUNKNOWN;
			goto out;
		}
	}

	if (flash_img_buffered_write(ctx, data, num_bytes, last) != 0) {
		rc = MGMT_ERR_EUNKNOWN;
		goto out;
	}

out:
	if (last || rc != MGMT_ERR_EOK) {
		k_free(ctx);
		ctx = NULL;
	}

	return rc;
}

#else
int
img_mgmt_write_image_data(unsigned int offset, const void *data, unsigned int num_bytes, bool last)
{
	static struct flash_img_context ctx;

	if (offset == 0) {
		if (flash_img_init_id(&ctx, g_img_mgmt_state.area_id) != 0) {
			return MGMT_ERR_EUNKNOWN;
		}
	}

	if (flash_img_buffered_write(&ctx, data, num_bytes, last) != 0) {
		return MGMT_ERR_EUNKNOWN;
	}

	return MGMT_ERR_EOK;
}
#endif

int
img_mgmt_erase_image_data(unsigned int off, unsigned int num_bytes)
{
	const struct flash_area *fa;
	int rc;

	if (off != 0) {
		rc = MGMT_ERR_EINVAL;
		goto end;
	}

	rc = flash_area_open(g_img_mgmt_state.area_id, &fa);
	if (rc != 0) {
		LOG_ERR("Can't bind to the flash area (err %d)", rc);
		rc = MGMT_ERR_EUNKNOWN;
		goto end;
	}

	/* align requested erase size to the erase-block-size */
	const struct device *dev = flash_area_get_device(fa);

	if (dev == NULL) {
		rc = MGMT_ERR_EUNKNOWN;
		goto end_fa;
	}
	struct flash_pages_info page;
	off_t page_offset = fa->fa_off + num_bytes - 1;

	rc = flash_get_page_info_by_offs(dev, page_offset, &page);
	if (rc != 0) {
		LOG_ERR("bad offset (0x%lx)", (long)page_offset);
		rc = MGMT_ERR_EUNKNOWN;
		goto end_fa;
	}

	size_t erase_size = page.start_offset + page.size - fa->fa_off;

	rc = flash_area_erase(fa, 0, erase_size);

	if (rc != 0) {
		LOG_ERR("image slot erase of 0x%zx bytes failed (err %d)", erase_size,
				rc);
		rc = MGMT_ERR_EUNKNOWN;
		goto end_fa;
	}

	LOG_INF("Erased 0x%zx bytes of image slot", erase_size);

#ifdef CONFIG_MCUBOOT_IMG_MANAGER
	/* Right now MCUmgr supports only mcuboot images.
	 * Above compilation swich might help to recognize mcuboot related
	 * code when supports for anothe bootloader will be introduced.
	 */

	/* erase the image trailer area if it was not erased */
	off = BOOT_TRAILER_IMG_STATUS_OFFS(fa);
	if (off >= erase_size) {
		rc = flash_get_page_info_by_offs(dev, fa->fa_off + off, &page);

		off = page.start_offset - fa->fa_off;
		erase_size = fa->fa_size - off;

		rc = flash_area_erase(fa, off, erase_size);
		if (rc != 0) {
			LOG_ERR("image slot trailer erase of 0x%zx bytes failed (err %d)",
					erase_size, rc);
			rc = MGMT_ERR_EUNKNOWN;
			goto end_fa;
		}

		LOG_INF("Erased 0x%zx bytes of image slot trailer", erase_size);
	}
#endif
	rc = 0;

end_fa:
	flash_area_close(fa);
end:
	return rc;
}

int
img_mgmt_swap_type(int slot)
{
	int image = img_mgmt_slot_to_image(slot);

	switch (mcuboot_swap_type_multi(image)) {
	case BOOT_SWAP_TYPE_NONE:
		return IMG_MGMT_SWAP_TYPE_NONE;
	case BOOT_SWAP_TYPE_TEST:
		return IMG_MGMT_SWAP_TYPE_TEST;
	case BOOT_SWAP_TYPE_PERM:
		return IMG_MGMT_SWAP_TYPE_PERM;
	case BOOT_SWAP_TYPE_REVERT:
		return IMG_MGMT_SWAP_TYPE_REVERT;
	default:
		return IMG_MGMT_SWAP_TYPE_UNKNOWN;
	}
}

/**
 * Verifies an upload request and indicates the actions that should be taken
 * during processing of the request.  This is a "read only" function in the
 * sense that it doesn't write anything to flash and doesn't modify any global
 * variables.
 *
 * @param req		The upload request to inspect.
 * @param action	On success, gets populated with information about how to process
 *			the request.
 *
 * @return 0 if processing should occur; A MGMT_ERR code if an error response should be sent
 *	   instead.
 */
int
img_mgmt_upload_inspect(const struct img_mgmt_upload_req *req,
			struct img_mgmt_upload_action *action)
{
	const struct image_header *hdr;
	struct image_version cur_ver;
	int rc;

	memset(action, 0, sizeof(*action));

	if (req->off == SIZE_MAX) {
		/* Request did not include an `off` field. */
		IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, img_mgmt_err_str_hdr_malformed);
		return MGMT_ERR_EINVAL;
	}

	if (req->off == 0) {
		/* First upload chunk. */
		if (req->img_data.len < sizeof(struct image_header)) {
			/*  Image header is the first thing in the image */
			IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, img_mgmt_err_str_hdr_malformed);
			return MGMT_ERR_EINVAL;
		}

		if (req->size == SIZE_MAX) {
			/* Request did not include a `len` field. */
			IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, img_mgmt_err_str_hdr_malformed);
			return MGMT_ERR_EINVAL;
		}
		action->size = req->size;

		hdr = (struct image_header *)req->img_data.value;
		if (hdr->ih_magic != IMAGE_MAGIC) {
			IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, img_mgmt_err_str_magic_mismatch);
			return MGMT_ERR_EINVAL;
		}

		if (req->data_sha.len > IMG_MGMT_DATA_SHA_LEN) {
			return MGMT_ERR_EINVAL;
		}

		/*
		 * If request includes proper data hash we can check whether there is
		 * upload in progress (interrupted due to e.g. link disconnection) with
		 * the same data hash so we can just resume it by simply including
		 * current upload offset in response.
		 */
		if ((req->data_sha.len > 0) && (g_img_mgmt_state.area_id != -1)) {
			if ((g_img_mgmt_state.data_sha_len == req->data_sha.len) &&
			    !memcmp(g_img_mgmt_state.data_sha, req->data_sha.value,
				    req->data_sha.len)) {
				return 0;
			}
		}

		action->area_id = img_mgmt_get_unused_slot_area_id(req->image);
		if (action->area_id < 0) {
			/* No slot where to upload! */
			IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, img_mgmt_err_str_no_slot);
			return MGMT_ERR_ENOENT;
		}

#if defined(CONFIG_IMG_MGMT_REJECT_DIRECT_XIP_MISMATCHED_SLOT)
		if (hdr->ih_flags & IMAGE_F_ROM_FIXED_ADDR) {
			rc = flash_area_open(action->area_id, &fa);
			if (rc) {
				IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action,
					img_mgmt_err_str_flash_open_failed);
				return MGMT_ERR_EUNKNOWN;
			}

			if (fa->fa_off != hdr->ih_load_addr) {
				IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action,
					img_mgmt_err_str_image_bad_flash_addr);
				flash_area_close(fa);
				return MGMT_ERR_EINVAL;
			}

			flash_area_close(fa);
		}
#endif


		if (req->upgrade) {
			/* User specified upgrade-only.  Make sure new image version is
			 * greater than that of the currently running image.
			 */
			rc = img_mgmt_my_version(&cur_ver);
			if (rc != 0) {
				return MGMT_ERR_EUNKNOWN;
			}

			if (img_mgmt_vercmp(&cur_ver, &hdr->ih_ver) >= 0) {
				IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action,
					img_mgmt_err_str_downgrade);
				return MGMT_ERR_EBADSTATE;
			}
		}

#ifndef CONFIG_IMG_ERASE_PROGRESSIVELY
		rc = img_mgmt_flash_check_empty(action->area_id);
		if (rc < 0) {
			return MGMT_ERR_EUNKNOWN;
		}

		action->erase = (rc == 0);
#endif
	} else {
		/* Continuation of upload. */
		action->area_id = g_img_mgmt_state.area_id;
		action->size = g_img_mgmt_state.size;

		if (req->off != g_img_mgmt_state.off) {
			/*
			 * Invalid offset. Drop the data, and respond with the offset we're
			 * expecting data for.
			 */
			return 0;
		}
	}

	action->write_bytes = req->img_data.len;
	action->proceed = true;
	IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, NULL);

	return 0;
}

int
img_mgmt_erased_val(int slot, uint8_t *erased_val)
{
	const struct flash_area *fa;
	int rc;
	int area_id = img_mgmt_flash_area_id(slot);

	if (area_id < 0) {
		return MGMT_ERR_EUNKNOWN;
	}

	rc = flash_area_open(area_id, &fa);
	if (rc != 0) {
		return MGMT_ERR_EUNKNOWN;
	}

	*erased_val = flash_area_erased_val(fa);
	flash_area_close(fa);

	return 0;
}
