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

#include <zephyr/zephyr.h>
#include <zephyr/ztest.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/devicetree.h>
#include <zephyr/storage/flash_map.h>

#if (CONFIG_NORDIC_QSPI_NOR - 0)
#define NORDIC_QSPI_NOR_NODE DT_INST(0, nordic_qspi_nor)
#define FLASH_NODEID NORDIC_QSPI_NOR_NODE
#define FLASH_TEST_REGION_OFFSET 0xff000

#if DT_NODE_HAS_PROP(NORDIC_QSPI_NOR_NODE, size_in_bytes)
#define TEST_AREA_MAX (DT_PROP(DT_INST(0, nordic_qspi_nor), size_in_bytes))
#else
#define TEST_AREA_MAX (DT_PROP(DT_INST(0, nordic_qspi_nor), size) / 8)
#endif

#elif defined(CONFIG_FLASH_MCUX_FLEXSPI_NOR)

#define FLASH_NODEID DT_INST(0, nxp_imx_flexspi_nor)
#define FLASH_TEST_REGION_OFFSET FLASH_AREA_OFFSET(storage)
#define TEST_AREA_MAX ((FLASH_AREA_SIZE(storage)) + (FLASH_TEST_REGION_OFFSET))
#elif defined(CONFIG_FLASH_MCUX_FLEXSPI_MX25UM51345G)

#define FLASH_NODEID DT_INST(0, nxp_imx_flexspi_mx25um51345g)
#define FLASH_TEST_REGION_OFFSET FLASH_AREA_OFFSET(storage)
#define TEST_AREA_MAX ((FLASH_AREA_SIZE(storage)) + (FLASH_TEST_REGION_OFFSET))
#else

/* SoC embedded NVM */
#define FLASH_NODEID DT_CHOSEN(zephyr_flash_controller)

#ifdef CONFIG_TRUSTED_EXECUTION_NONSECURE
#define FLASH_TEST_REGION_OFFSET FLASH_AREA_OFFSET(image_1_nonsecure)
#define TEST_AREA_MAX (FLASH_TEST_REGION_OFFSET +\
		       FLASH_AREA_SIZE(image_1_nonsecure))
#else
#define FLASH_TEST_REGION_OFFSET FLASH_AREA_OFFSET(storage)
#define TEST_AREA_MAX (FLASH_TEST_REGION_OFFSET + FLASH_AREA_SIZE(storage))
#endif

#endif

#define EXPECTED_SIZE	256
#define CANARY		0xff

static const struct device *flash_dev = DEVICE_DT_GET(FLASH_NODEID);
static struct flash_pages_info page_info;
static uint8_t __aligned(4) expected[EXPECTED_SIZE];

static void test_setup(void)
{
	int rc;

	zassert_true(device_is_ready(flash_dev), NULL);

	const struct flash_parameters *flash_params =
			flash_get_parameters(flash_dev);

	/* For tests purposes use page (in nrf_qspi_nor page = 64 kB) */
	flash_get_page_info_by_offs(flash_dev, FLASH_TEST_REGION_OFFSET,
				    &page_info);

	/* Check if test region is not empty */
	uint8_t buf[EXPECTED_SIZE];

	rc = flash_read(flash_dev, FLASH_TEST_REGION_OFFSET,
			buf, EXPECTED_SIZE);
	zassert_equal(rc, 0, "Cannot read flash");

	/* Fill test buffer with random data */
	for (int i = 0; i < EXPECTED_SIZE; i++) {
		expected[i] = i;
	}

	/* Check if tested region fits in flash */
	zassert_true((FLASH_TEST_REGION_OFFSET + EXPECTED_SIZE) < TEST_AREA_MAX,
		     "Test area exceeds flash size");

	/* Check if flash is cleared */
	bool is_buf_clear = true;

	for (off_t i = 0; i < EXPECTED_SIZE; i++) {
		if (buf[i] != flash_params->erase_value) {
			is_buf_clear = false;
			break;
		}
	}

	if (!is_buf_clear) {
		/* erase page */
		rc = flash_erase(flash_dev, page_info.start_offset,
				 page_info.size);
		zassert_equal(rc, 0, "Flash memory not properly erased");
	}

}

static void test_read_unaligned_address(void)
{
	int rc;
	uint8_t buf[EXPECTED_SIZE];

	rc = flash_write(flash_dev,
			 page_info.start_offset,
			 expected, EXPECTED_SIZE);
	zassert_equal(rc, 0, "Cannot write to flash");

	/* read buffer length*/
	for (off_t len = 0; len < 25; len++) {
		/* address offset */
		for (off_t ad_o = 0; ad_o < 4; ad_o++) {
			/* buffer offset; leave space for buffer guard */
			for (off_t buf_o = 1; buf_o < 5; buf_o++) {
				/* buffer overflow protection */
				buf[buf_o - 1] = CANARY;
				buf[buf_o + len] = CANARY;
				memset(buf + buf_o, 0, len);
				rc = flash_read(flash_dev,
						page_info.start_offset + ad_o,
						buf + buf_o, len);
				zassert_equal(rc, 0, "Cannot read flash");
				zassert_equal(memcmp(buf + buf_o,
						expected + ad_o,
						len),
					0, "Flash read failed at len=%d, "
					"ad_o=%d, buf_o=%d", len, ad_o, buf_o);
				/* check buffer guards */
				zassert_equal(buf[buf_o - 1], CANARY,
					"Buffer underflow at len=%d, "
					"ad_o=%d, buf_o=%d", len, ad_o, buf_o);
				zassert_equal(buf[buf_o + len], CANARY,
					"Buffer overflow at len=%d, "
					"ad_o=%d, buf_o=%d", len, ad_o, buf_o);
			}
		}
	}
}

void test_main(void)
{
	ztest_test_suite(flash_driver_test,
		ztest_unit_test(test_setup),
		ztest_unit_test(test_read_unaligned_address)
	);

	ztest_run_test_suite(flash_driver_test);
}
