/*
 * Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr.h>
#include <ztest.h>
#include <devicetree.h>
#include <sys/printk.h>
#include <drivers/flash.h>
#include <random/rand32.h>
#include <soc/soc_memory_layout.h>

/* definitions used in Flash & RAM operations */
#define SPIRAM_ALLOC_SIZE               (24 * 1024)
#define FLASH_PAGE_TESTED               (1023)
#define FLASH_PAGE_OFFSET               (0)
#define FLASH_BYTE_PATTERN              (0x38)
#define FLASH_READBACK_LEN              (1024)
#define FLASH_ITERATIONS                (10)
#define PSRAM_ITERATIONS                (10)

/* common thread definitions */
#define STACKSIZE 1024
#define PRIORITY 7

#ifndef DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL
#define DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL ""
#endif

static const struct device *flash_dev;
static struct flash_pages_info page_info;
static int *mem;
uint8_t flash_fill_buff[FLASH_READBACK_LEN];
uint8_t flash_read_buff[FLASH_READBACK_LEN];

static uint8_t flash_val = FLASH_BYTE_PATTERN;
static bool buffer_ready;
static bool needs_fill = true;
static bool unfinished_tasks = true;
static struct k_spinlock lock;

struct coex_test_results {
	bool using_ext_ram;
	int flash_cnt;
	bool psram_ok;
};
static struct coex_test_results coex_result;

static void buffer_fill(void)
{
	while (needs_fill) {
		if (!buffer_ready) {
			k_spinlock_key_t key = k_spin_lock(&lock);

			memset(flash_fill_buff, ++flash_val, sizeof(flash_fill_buff));
			buffer_ready = true;
			k_spin_unlock(&lock, key);
		}
		k_usleep(10);
	}
	while (true) {
		k_usleep(1);
	}
}

static void check_flash(void)
{
	int cnt = 0;

	for (size_t i = 0; i < sizeof(flash_read_buff); ++i) {
		if (flash_read_buff[i] == (FLASH_BYTE_PATTERN + FLASH_ITERATIONS)) {
			++cnt;
		}
	}
	coex_result.flash_cnt = cnt;
	unfinished_tasks = false;
}

static int do_erase(off_t offset, size_t size)
{
	int rc;

	rc = flash_erase(flash_dev, offset, size);
	if (rc) {
		TC_ERROR("flash erase has failed\n");
		return rc;
	}

	return rc;
}

static int page_erase(void)
{
	int rc;

	rc = flash_get_page_info_by_idx(flash_dev, FLASH_PAGE_TESTED, &page_info);
	if (rc) {
		return rc;
	}

	rc = do_erase(page_info.start_offset, page_info.size);
	if (rc) {
		return rc;
	}

	return rc;
}

static int page_read(void)
{
	int rc = flash_get_page_info_by_idx(flash_dev, FLASH_PAGE_TESTED, &page_info);

	if (rc) {
		TC_ERROR("could not read flash info\n");
		return rc;
	}
	rc = flash_read(flash_dev,
			page_info.start_offset + FLASH_PAGE_OFFSET,
			flash_read_buff,
			sizeof(flash_read_buff));
	if (rc) {
		TC_ERROR("flash read back has failed\n");
		return rc;
	}

	return 0;
}

static int page_write(void)
{
	int rc = flash_get_page_info_by_idx(flash_dev, FLASH_PAGE_TESTED, &page_info);

	if (rc) {
		TC_ERROR("could not retrieve flash info\n");
		return rc;
	}

	rc = flash_write(flash_dev,
			page_info.start_offset + FLASH_PAGE_OFFSET,
			flash_fill_buff,
			sizeof(flash_fill_buff));
	if (rc) {
		TC_ERROR("could not write to flash\n");
		return rc;
	}

	return 0;
}

static bool do_flashop(void)
{
	int rc = page_write();

	if (rc) {
		return false;
	}

	return true;
}

static void fill_value(int value)
{
	int i;

	/* fills external RAM with given value */
	for (i = 0; i < (SPIRAM_ALLOC_SIZE / sizeof(int)); ++i) {
		mem[i] = value;
	}
}

static bool check_psram(int value)
{
	int *ptr = mem;

	/* checks if external RAM is filled with the expected value */
	for (size_t i = 0; i < (SPIRAM_ALLOC_SIZE / sizeof(int)); ++i) {
		if (*ptr++ != value) {
			return false;
		}
	}
	return true;
}

void psram_test(void)
{
	uint32_t sleep_ms = 10;
	int rand_val;

	for (size_t i = 0; i < PSRAM_ITERATIONS; ++i) {
		rand_val = (int)sys_rand32_get();
		fill_value(rand_val);
		k_msleep(sleep_ms);
	}
	if (check_psram(rand_val)) {
		coex_result.psram_ok = true;
	} else {
		coex_result.psram_ok = false;
	}
	while (true) {
		k_usleep(1);
	}
}

void psram_init(void)
{
	mem = k_malloc(SPIRAM_ALLOC_SIZE);
	if (!mem) {
		TC_ERROR("SPIRAM allocation has failed\n");
	}

	if (!esp_ptr_external_ram(mem)) {
		coex_result.using_ext_ram = false;
		TC_ERROR("allocation is not within specified bounds\n");
		return;
	}

	coex_result.using_ext_ram = true;
	psram_test();
}

void flash_test(void)
{
	uint32_t sleep_ms = 15;

	for (size_t i = 0; i < FLASH_ITERATIONS; ++i) {
		page_erase();
		if (buffer_ready) {
			k_spinlock_key_t key = k_spin_lock(&lock);

			do_flashop();
			buffer_ready = false;
			k_spin_unlock(&lock, key);
		}
		k_msleep(sleep_ms);
	}
	needs_fill = false;
	page_read();
	check_flash();
	while (true) {
		k_usleep(1);
	}
}

void flash_init(void)
{
	flash_dev = device_get_binding(DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
	if (!flash_dev) {
		TC_ERROR("flash controller initialization failedi\n");
	}
	flash_test();
}

void test_using_spiram(void)
{
	zassert_equal(true, coex_result.using_ext_ram, "external RAM is not being used");
}

void test_flash_integrity(void)
{
	zassert_equal(FLASH_READBACK_LEN, coex_result.flash_cnt, "flash integrity test failed");
}

void test_ram_integrity(void)
{
	zassert_equal(true, coex_result.psram_ok, "SPIRAM integrity test failed");
}

void test_main(void)
{
	while (unfinished_tasks) {
		k_usleep(1);
	}

	ztest_test_suite(cache_coex_test,
			ztest_unit_test(test_using_spiram),
			ztest_unit_test(test_flash_integrity),
			ztest_unit_test(test_ram_integrity)
	);

	ztest_run_test_suite(cache_coex_test);
}

K_THREAD_DEFINE(psram_id, STACKSIZE, psram_init, NULL, NULL, NULL, PRIORITY, 0, 0);
K_THREAD_DEFINE(flash_id, STACKSIZE, flash_init, NULL, NULL, NULL, PRIORITY, 0, 0);
K_THREAD_DEFINE(buffer_id, STACKSIZE, buffer_fill, NULL, NULL, NULL, PRIORITY, 0, 0);
