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

#include <ztest.h>
#include <storage/flash_map.h>
#include <dfu/mcuboot.h>
#include <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 _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;
	struct flash_pages_info page;
	const struct device *sf_dev;

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

	sf_dev = flash_area_get_device(fa);

	ret = flash_get_page_info_by_offs(sf_dev, fa->fa_size - 1, &page);
	ret = flash_erase(sf_dev, page.start_offset, page.size);

	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");
	}
}

void test_request_upgrade_multi(void)
{
	_test_request_upgrade_n(FLASH_AREA_ID(image_1), 0, 0);
	_test_request_upgrade_n(FLASH_AREA_ID(image_3), 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;
	struct flash_pages_info page;
	const struct device *sf_dev;

	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.");

	sf_dev = flash_area_get_device(fa);

	ret = flash_get_page_info_by_offs(sf_dev, 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.");

	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");
}

void test_write_confirm_multi(void)
{
	_test_write_confirm_n(FLASH_AREA_ID(image_0), 0);
	_test_write_confirm_n(FLASH_AREA_ID(image_2), 1);
}

void test_main(void)
{
	ztest_test_suite(test_mcuboot_interface,
			 ztest_unit_test(test_request_upgrade_multi),
			 ztest_unit_test(test_write_confirm_multi));
	ztest_run_test_suite(test_mcuboot_interface);
}
