/*
 * Copyright (c) 2017 Nordic Semiconductor ASA
 * Copyright (c) 2020 Gerson Fernando Budke <nandojve@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <ztest.h>
#include <storage/flash_map.h>
#include <dfu/flash_img.h>

void test_init_id(void)
{
	struct flash_img_context ctx_no_id;
	struct flash_img_context ctx_id;
	int ret;

	ret = flash_img_init(&ctx_no_id);
	zassert_true(ret == 0, "Flash img init");

	ret = flash_img_init_id(&ctx_id, FLASH_AREA_ID(image_1));
	zassert_true(ret == 0, "Flash img init id");

	/* Verify that the default partition ID is IMAGE_1 */
	zassert_equal(ctx_id.flash_area, ctx_no_id.flash_area,
		      "Default partition ID is incorrect");

	/* Note: IMAGE_0, not IMAGE_1 as above */
	ret = flash_img_init_id(&ctx_id, FLASH_AREA_ID(image_0));
	zassert_true(ret == 0, "Flash img init id");

	zassert_equal(ctx_id.flash_area->fa_id, FLASH_AREA_ID(image_0),
		      "Partition ID is not set correctly");
}

void test_collecting(void)
{
	const struct flash_area *fa;
	struct flash_img_context ctx;
	uint32_t i, j;
	uint8_t data[5], temp, k;
	int ret;

	ret = flash_img_init(&ctx);
	zassert_true(ret == 0, "Flash img init");

#ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
	uint8_t erase_buf[8];
	(void)memset(erase_buf, 0xff, sizeof(erase_buf));

	ret = flash_area_open(FLASH_AREA_ID(image_1), &fa);
	if (ret) {
		printf("Flash driver was not found!\n");
		return;
	}

	/* ensure image payload area dirt */
	for (i = 0U; i < 300 * sizeof(data) / sizeof(erase_buf); i++) {
		ret = flash_area_write(fa, i * sizeof(erase_buf), erase_buf,
				       sizeof(erase_buf));
		zassert_true(ret == 0, "Flash write failure (%d)", ret);
	}

	/* ensure that the last page dirt */
	ret = flash_area_write(fa, fa->fa_size - sizeof(erase_buf), erase_buf,
			       sizeof(erase_buf));
	zassert_true(ret == 0, "Flash write failure (%d)", ret);
#else
	ret = flash_area_erase(ctx.flash_area, 0, ctx.flash_area->fa_size);
	zassert_true(ret == 0, "Flash erase failure (%d)", ret);
#endif

	zassert(flash_img_bytes_written(&ctx) == 0, "pass", "fail");

	k = 0U;
	for (i = 0U; i < 300; i++) {
		for (j = 0U; j < ARRAY_SIZE(data); j++) {
			data[j] = k++;
		}
		ret = flash_img_buffered_write(&ctx, data, sizeof(data), false);
		zassert_true(ret == 0, "image collection fail: %d\n", ret);
	}

	zassert(flash_img_buffered_write(&ctx, data, 0, true) == 0, "pass",
					 "fail");


	ret = flash_area_open(FLASH_AREA_ID(image_1), &fa);
	if (ret) {
		printf("Flash driver was not found!\n");
		return;
	}

	k = 0U;
	for (i = 0U; i < 300 * sizeof(data); i++) {
		zassert(flash_area_read(fa, i, &temp, 1) == 0, "pass", "fail");
		zassert(temp == k, "pass", "fail");
		k++;
	}

#ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
	uint8_t buf[sizeof(erase_buf)];

	ret = flash_area_read(fa, fa->fa_size - sizeof(buf), buf, sizeof(buf));
	zassert_true(ret == 0, "Flash read failure (%d)", ret);
	zassert_true(memcmp(erase_buf, buf, sizeof(buf)) == 0,
		     "Image trailer was not cleared");
#endif
}

void test_check_flash(void)
{
	/* echo $'0123456789abcdef\nfedcba9876543201' > tst.sha
	 * hexdump tst.sha
	 */
	uint8_t tst_vec[] = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
			      0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
			      0x0a, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x39,
			      0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
			      0x30, 0x0a };
	/* sha256sum tst.sha */
	uint8_t tst_sha[] = { 0xc6, 0xb6, 0x7c, 0x46, 0xe7, 0x2e, 0x14, 0x17,
			      0x49, 0xa4, 0xd2, 0xf1, 0x38, 0x58, 0xb2, 0xa7,
			      0x54, 0xaf, 0x6d, 0x39, 0x50, 0x6b, 0xd5, 0x41,
			      0x90, 0xf6, 0x18, 0x1a, 0xe0, 0xc2, 0x7f, 0x98 };

	struct flash_img_check fic = { NULL, 0 };
	struct flash_img_context ctx;
	int ret;

	ret = flash_img_init_id(&ctx, FLASH_AREA_ID(image_1));
	zassert_true(ret == 0, "Flash img init 1");
	ret = flash_area_erase(ctx.flash_area, 0, ctx.flash_area->fa_size);
	zassert_true(ret == 0, "Flash erase failure (%d)\n", ret);
	ret = flash_img_buffered_write(&ctx, tst_vec, sizeof(tst_vec), true);
	zassert_true(ret == 0, "Flash img buffered write\n");

	ret = flash_img_check(NULL, NULL, 0);
	zassert_true(ret == -EINVAL, "Flash img check params 1, 2\n");
	ret = flash_img_check(NULL, &fic, 0);
	zassert_true(ret == -EINVAL, "Flash img check params 2\n");
	ret = flash_img_check(&ctx, NULL, 0);
	zassert_true(ret == -EINVAL, "Flash img check params 1\n");

	ret = flash_img_check(&ctx, &fic, FLASH_AREA_ID(image_1));
	zassert_true(ret == -EINVAL, "Flash img check fic match\n");
	fic.match = tst_sha;
	ret = flash_img_check(&ctx, &fic, FLASH_AREA_ID(image_1));
	zassert_true(ret == -EINVAL, "Flash img check fic len\n");
	fic.clen = sizeof(tst_vec);

	ret = flash_img_check(&ctx, &fic, FLASH_AREA_ID(image_1));
	zassert_true(ret == 0, "Flash img check\n");
	tst_sha[0] = 0x00;
	ret = flash_img_check(&ctx, &fic, FLASH_AREA_ID(image_1));
	zassert_false(ret == 0, "Flash img check wrong sha\n");

	flash_area_close(ctx.flash_area);
}

void test_main(void)
{
	ztest_test_suite(test_util,
			ztest_unit_test(test_collecting),
			ztest_unit_test(test_init_id),
			ztest_unit_test(test_check_flash)
			);
	ztest_run_test_suite(test_util);
}
