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

#include <zephyr/ztest.h>
#include <zephyr/storage/flash_map.h>
#include <zephyr/bluetooth/mesh.h>

#include "mesh/blob.h"

#define SLOT1_PARTITION		slot1_partition
#define SLOT1_PARTITION_ID	FIXED_PARTITION_ID(SLOT1_PARTITION)
#define SLOT1_PARTITION_SIZE	FIXED_PARTITION_SIZE(SLOT1_PARTITION)
/* Chunk size is set to value that is not multiple of 4, to verify that chunks are written correctly
 * even if they are not aligned with word length used in flash
 */
#define CHUNK_SIZE		65

static struct bt_mesh_blob_io_flash blob_flash_stream;

static size_t chunk_size(const struct bt_mesh_blob_block *block,
				uint16_t chunk_idx)
{
	if ((chunk_idx == block->chunk_count - 1) &&
	    (block->size % CHUNK_SIZE)) {
		return block->size % CHUNK_SIZE;
	}

	return CHUNK_SIZE;
}

static uint8_t block_size_to_log(size_t size)
{
	uint8_t block_size_log = 0;

	while (size > 1) {
		size = size / 2;
		block_size_log++;
	}

	return block_size_log;
}

ZTEST_SUITE(blob_io_flash, NULL, NULL, NULL, NULL, NULL);

ZTEST(blob_io_flash, test_chunk_read)
{
	const struct flash_area *fa = NULL;
	struct bt_mesh_blob_xfer xfer;
	struct bt_mesh_blob_block block = { 0 };
	struct bt_mesh_blob_chunk chunk = { 0 };
	size_t remaining = SLOT1_PARTITION_SIZE;
	off_t block_idx = 0;
	uint16_t chunk_idx = 0;
	uint8_t chunk_data[CHUNK_SIZE];
	uint8_t test_data[SLOT1_PARTITION_SIZE];
	uint8_t ctrl_data[SLOT1_PARTITION_SIZE];
	size_t tests_data_offset = 0;
	int i, err;

	/* Fill test data with pattern */
	for (i = 0; i < SLOT1_PARTITION_SIZE; i++) {
		test_data[i] = i % 0xFF;
	}

	err = flash_area_open(SLOT1_PARTITION_ID, &fa);
	zassert_equal(err, 0, "Preparing test data failed with err=%d", err);

	err = flash_area_erase(fa, 0, ARRAY_SIZE(ctrl_data));
	zassert_equal(err, 0, "Preparing test data failed with err=%d", err);

	err = flash_area_write(fa, 0, test_data, ARRAY_SIZE(ctrl_data));
	zassert_equal(err, 0, "Preparing test data failed with err=%d", err);

	err = flash_area_read(fa, 0, ctrl_data, ARRAY_SIZE(ctrl_data));
	zassert_equal(err, 0, "Preparing test data failed with err=%d", err);

	zassert_mem_equal(ctrl_data, test_data, ARRAY_SIZE(ctrl_data),
			  "Incorrect data written into flash");

	memset(ctrl_data, 0, SLOT1_PARTITION_SIZE);

	flash_area_close(fa);

	err = bt_mesh_blob_io_flash_init(&blob_flash_stream,
					 SLOT1_PARTITION_ID, 0);
	zassert_equal(err, 0, "BLOB I/O init failed with err=%d", err);

	err = blob_flash_stream.io.open(&blob_flash_stream.io, &xfer, BT_MESH_BLOB_READ);
	zassert_equal(err, 0, "BLOB I/O open failed with err=%d", err);

	chunk.data = chunk_data;

	/* Simulate reading whole partition divided into blocks and chunk of maximum sizes */
	while (remaining > 0) {
		block.chunk_count =
			DIV_ROUND_UP(CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX,
					 CHUNK_SIZE);
		block.size = remaining > CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX
				     ? CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX
				     : remaining;

		/* BLOB Client should do nothing to flash area as it's in read mode */
		err = blob_flash_stream.io.block_start(&blob_flash_stream.io, &xfer, &block);
		zassert_equal(err, 0, "BLOB I/O open failed with err=%d", err);

		/* `block_start` in write mode will erase flash pages that can fit block.
		 * Assert that at least block size of data was not erased in read mode
		 */
		flash_area_read(blob_flash_stream.area, block.offset, ctrl_data, block.size);
		zassert_mem_equal(ctrl_data, &test_data[block.offset], block.size,
				  "Flash data was altered by `block_start` in read mode");

		memset(ctrl_data, 0, SLOT1_PARTITION_SIZE);

		block.offset = block_idx * (1 << block_size_to_log(block.size));

		for (i = 0; i < block.chunk_count; i++) {
			chunk.size = chunk_size(&block, chunk_idx);
			chunk.offset = CHUNK_SIZE * chunk_idx;

			err = blob_flash_stream.io.rd(&blob_flash_stream.io, &xfer, &block, &chunk);
			zassert_equal(err, 0, "BLOB I/O read failed with err=%d off=%d len=%d",
				      err, block.offset + chunk.offset, chunk.size);

			zassert_mem_equal(&chunk_data, &test_data[tests_data_offset], chunk.size,
					  "Incorrect data written into flash");
			chunk_idx++;

			remaining -= chunk.size;
			tests_data_offset += chunk.size;
		}
		block_idx++;
		chunk_idx = 0;
	}

	/* We read whole sector as BLOB. Try to increment every offset by one and read,
	 * which should attempt to read outside flash area
	 */
	chunk.offset++;
	err = blob_flash_stream.io.rd(&blob_flash_stream.io, &xfer, &block, &chunk);
	zassert_false(err == 0, "Read outside flash area successful");

	chunk.offset--;
	block.offset++;
	err = blob_flash_stream.io.rd(&blob_flash_stream.io, &xfer, &block, &chunk);
	zassert_false(err == 0, "Read outside flash area successful");

	block.offset--;
	blob_flash_stream.offset++;
	err = blob_flash_stream.io.rd(&blob_flash_stream.io, &xfer, &block, &chunk);
	zassert_false(err == 0, "Read outside flash area successful");

	blob_flash_stream.io.close(&blob_flash_stream.io, &xfer);
}

ZTEST(blob_io_flash, test_chunk_write)
{
	struct bt_mesh_blob_xfer xfer;
	struct bt_mesh_blob_block block = { 0 };
	struct bt_mesh_blob_chunk chunk = { 0 };
	size_t remaining = SLOT1_PARTITION_SIZE;
	off_t block_idx = 0;
	uint16_t chunk_idx = 0;
	uint8_t chunk_data[CHUNK_SIZE];
	/* 3 is maximum length of padding at the end of written chunk */
	uint8_t chunk_ctrl_data[CHUNK_SIZE + 3];
	uint8_t end_padding_len;
	uint8_t test_data[SLOT1_PARTITION_SIZE];
	uint8_t erased_block_data[CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX];
	uint8_t ctrl_data[SLOT1_PARTITION_SIZE];
	size_t tests_data_offset = 0;
	int i, j, err;

	/* Fill test data with pattern */
	for (i = 0; i < SLOT1_PARTITION_SIZE; i++) {
		test_data[i] = i % 0xFF;
	}

	err = bt_mesh_blob_io_flash_init(&blob_flash_stream,
					 SLOT1_PARTITION_ID, 0);
	zassert_equal(err, 0, "BLOB I/O init failed with err=%d", err);

	err = blob_flash_stream.io.open(&blob_flash_stream.io, &xfer, BT_MESH_BLOB_WRITE);
	zassert_equal(err, 0, "BLOB I/O open failed with err=%d", err);

	chunk.data = chunk_data;

	memset(erased_block_data, flash_area_erased_val(blob_flash_stream.area),
	       CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX);
	/* Simulate writing whole partition divided into blocks and chunk of maximum sizes */
	while (remaining > 0) {
		block.chunk_count =
			DIV_ROUND_UP(CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX,
					 CHUNK_SIZE);
		block.size = remaining > CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX
				     ? CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX
				     : remaining;
		block.offset = block_idx * (1 << block_size_to_log(block.size));

		err = blob_flash_stream.io.block_start(&blob_flash_stream.io, &xfer, &block);
		zassert_equal(err, 0, "BLOB I/O open failed with err=%d", err);

		flash_area_read(blob_flash_stream.area, block.offset,
				ctrl_data, block.size);

		zassert_mem_equal(ctrl_data, erased_block_data, block.size,
				  "Flash data was not erased by `block_start` in write mode");

		memset(ctrl_data, 0, SLOT1_PARTITION_SIZE);

		for (i = 0; i < block.chunk_count; i++) {
			chunk.size = chunk_size(&block, chunk_idx);
			chunk.offset = CHUNK_SIZE * chunk_idx;

			memcpy(chunk.data,
			       &test_data[chunk.offset + block.offset],
			       chunk.size);

			err = blob_flash_stream.io.wr(&blob_flash_stream.io, &xfer, &block, &chunk);
			zassert_equal(err, 0, "BLOB I/O write failed with err=%d", err);

			/* To calculate end padding length we must calculate size of whole buffer
			 * and subtract start offset length and chunk size
			 */
			end_padding_len =
				ROUND_UP((block.offset + chunk.offset) %
					 flash_area_align(blob_flash_stream.area) +
					 chunk.size, flash_area_align(blob_flash_stream.area)) -
				(block.offset + chunk.offset) %
				flash_area_align(blob_flash_stream.area) - chunk.size;

			flash_area_read(blob_flash_stream.area, block.offset + chunk.offset,
					chunk_ctrl_data, chunk.size + end_padding_len);

			zassert_mem_equal(chunk_ctrl_data, chunk_data, chunk.size,
					  "Incorrect data written into flash");

			/* Assert that nothing was written into end padding */
			for (j = 1; j <= end_padding_len; j++) {
				zassert_equal(chunk_ctrl_data[chunk.size + j],
					      flash_area_erased_val(blob_flash_stream.area));
			}
			chunk_idx++;

			remaining -= chunk.size;
			tests_data_offset += chunk.size;
		}

		block_idx++;
		chunk_idx = 0;
	}

	flash_area_read(blob_flash_stream.area, 0, ctrl_data, SLOT1_PARTITION_SIZE);
	zassert_mem_equal(ctrl_data, test_data, SLOT1_PARTITION_SIZE,
			  "Incorrect chunks written into flash");

	/* We wrote whole sector as BLOB. Try to increment every offset by one and write,
	 * which should attempt to write outside flash area
	 */
	chunk.offset++;
	err = blob_flash_stream.io.wr(&blob_flash_stream.io, &xfer, &block, &chunk);
	zassert_false(err == 0, "Write outside flash area successful");

	chunk.offset--;
	block.offset++;
	err = blob_flash_stream.io.wr(&blob_flash_stream.io, &xfer, &block, &chunk);
	zassert_false(err == 0, "Write outside flash area successful");

	block.offset--;
	blob_flash_stream.offset++;
	err = blob_flash_stream.io.wr(&blob_flash_stream.io, &xfer, &block, &chunk);
	zassert_false(err == 0, "Write outside flash area successful");

	blob_flash_stream.io.close(&blob_flash_stream.io, &xfer);
}
