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

#include <zephyr/ztest.h>
#include <zephyr/storage/flash_map.h>
#include <bootutil/bootutil_public.h>
#include <zephyr/dfu/mcuboot.h>
#include <zephyr/drivers/flash.h>

#define BOOT_MAGIC_VAL_W0 0xf395c277
#define BOOT_MAGIC_VAL_W1 0x7fefd260
#define BOOT_MAGIC_VAL_W2 0x0f505235
#define BOOT_MAGIC_VAL_W3 0x8079b62c
#define BOOT_MAGIC_VALUES {BOOT_MAGIC_VAL_W0, BOOT_MAGIC_VAL_W1,\
			   BOOT_MAGIC_VAL_W2, BOOT_MAGIC_VAL_W3 }

static void erase_image_status_page(const struct flash_area *fa)
{
	int ret;
	struct flash_pages_info page;
	const struct device *sf_dev;

	sf_dev = flash_area_get_device(fa);

	/* Erase flash page to which image status belongs. */
	ret = flash_get_page_info_by_offs(sf_dev, fa->fa_off + fa->fa_size - 1,
					  &page);
	zassert_true(ret == 0, "can't get the trailer's flash page info.");

	ret = flash_erase(sf_dev, page.start_offset, page.size);
	zassert_true(ret == 0, "can't erase the trailer flash page.");
}

static void _test_request_upgrade_n(uint8_t fa_id, int img_index, int confirmed)
{
	const struct flash_area *fa;
	const uint32_t expectation[6] = {
		0xffffffff,
		0xffffffff,
		BOOT_MAGIC_VAL_W0,
		BOOT_MAGIC_VAL_W1,
		BOOT_MAGIC_VAL_W2,
		BOOT_MAGIC_VAL_W3
	};
	uint32_t readout[ARRAY_SIZE(expectation)];
	int ret;

	ret = flash_area_open(fa_id, &fa);
	zassert_true(ret == 0, "can't open the images's flash area.");

	erase_image_status_page(fa);

	ret = (confirmed) ? BOOT_UPGRADE_PERMANENT : BOOT_UPGRADE_TEST;
	zassert_true(boot_request_upgrade_multi(img_index, ret) == 0,
		     "Can' request the upgrade of the %d. image.", img_index);

	ret = flash_area_read(fa, fa->fa_size - sizeof(expectation),
			      &readout, sizeof(readout));
	zassert_true(ret == 0, "Read from flash");

	if (confirmed) {
		zassert_true(memcmp(&expectation[2], &readout[2],
				    sizeof(expectation) -
				    2 * sizeof(expectation[0])) == 0,
				    "unexpected trailer value");

		zassert_equal(1, readout[0] & 0xff, "confirmation error");
	} else {
		zassert_true(memcmp(expectation, readout,
		sizeof(expectation)) == 0, "unexpected trailer value");
	}
}

ZTEST(mcuboot_multi, test_request_upgrade_multi)
{
	_test_request_upgrade_n(FIXED_PARTITION_ID(slot1_partition), 0, 0);
	_test_request_upgrade_n(FIXED_PARTITION_ID(slot3_partition), 1, 1);
}

static void _test_write_confirm_n(uint8_t fa_id, int img_index)
{
	const uint32_t img_magic[4] = BOOT_MAGIC_VALUES;
	uint32_t readout[ARRAY_SIZE(img_magic)];
	uint8_t flag[BOOT_MAX_ALIGN];
	const struct flash_area *fa;
	int ret;

	flag[0] = 0x01;
	memset(&flag[1], 0xff, sizeof(flag) - 1);

	ret = flash_area_open(fa_id, &fa);
	zassert_true(ret == 0, "can't open the images's flash area.");

	erase_image_status_page(fa);

	ret = flash_area_read(fa, fa->fa_size - sizeof(img_magic),
			      &readout, sizeof(img_magic));
	zassert_true(ret == 0, "Read from flash");

	if (memcmp(img_magic, readout, sizeof(img_magic)) != 0) {
		ret = flash_area_write(fa, fa->fa_size - 16,
				       img_magic, 16);
		zassert_true(ret == 0, "Write to flash");
	}

	/* set copy-done flag */
	ret = flash_area_write(fa, fa->fa_size - 32, &flag, sizeof(flag));
	zassert_true(ret == 0, "Write to flash");

	ret = boot_write_img_confirmed_multi(img_index);
	zassert(ret == 0, "pass", "fail (%d)", ret);

	ret = flash_area_read(fa, fa->fa_size - 24, readout,
			      sizeof(readout[0]));
	zassert_true(ret == 0, "Read from flash");

	zassert_equal(1, readout[0] & 0xff, "confirmation error");
}

ZTEST(mcuboot_multi, test_write_confirm_multi)
{
	_test_write_confirm_n(FIXED_PARTITION_ID(slot0_partition), 0);
	_test_write_confirm_n(FIXED_PARTITION_ID(slot2_partition), 1);
}

ZTEST_SUITE(mcuboot_multi, NULL, NULL, NULL, NULL, NULL);
