/*
 * Copyright (c) 2016 Intel Corporation.
 * Copyright (c) 2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <string.h>
#include <zephyr/types.h>
#include <zephyr/sys/__assert.h>
#include <zephyr/sys/util.h>
#include <zephyr/drivers/disk.h>
#include <errno.h>
#include <zephyr/init.h>
#include <zephyr/device.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/storage/flash_map.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(flashdisk, CONFIG_FLASHDISK_LOG_LEVEL);

struct flashdisk_data {
	struct disk_info info;
	struct k_mutex lock;
	const unsigned int area_id;
	const off_t offset;
	uint8_t *const cache;
	const size_t cache_size;
	const size_t size;
	const size_t sector_size;
	size_t page_size;
	off_t cached_addr;
	bool cache_valid;
	bool cache_dirty;
};

#define GET_SIZE_TO_BOUNDARY(start, block_size) \
	(block_size - (start & (block_size - 1)))

static int disk_flash_access_status(struct disk_info *disk)
{
	LOG_DBG("status : %s", disk->dev ? "okay" : "no media");
	if (!disk->dev) {
		return DISK_STATUS_NOMEDIA;
	}

	return DISK_STATUS_OK;
}

static int flashdisk_init_runtime(struct flashdisk_data *ctx,
				  const struct flash_area *fap)
{
	int rc;
	struct flash_pages_info page;
	off_t offset;

	rc = flash_get_page_info_by_offs(ctx->info.dev, ctx->offset, &page);
	if (rc < 0) {
		LOG_ERR("Error %d while getting page info", rc);
		return rc;
	}

	ctx->page_size = page.size;
	LOG_INF("Initialize device %s", ctx->info.name);
	LOG_INF("offset %lx, sector size %zu, page size %zu, volume size %zu",
		(long)ctx->offset, ctx->sector_size, ctx->page_size, ctx->size);

	if (ctx->cache_size == 0) {
		/* Read-only flashdisk, no flash partition constraints */
		LOG_INF("%s is read-only", ctx->info.name);
		return 0;
	}

	if (IS_ENABLED(CONFIG_FLASHDISK_VERIFY_PAGE_LAYOUT)) {
		if (ctx->offset != page.start_offset) {
			LOG_ERR("Disk %s does not start at page boundary",
				ctx->info.name);
			return -EINVAL;
		}

		offset = ctx->offset + page.size;
		while (offset < ctx->offset + ctx->size) {
			rc = flash_get_page_info_by_offs(ctx->info.dev, offset, &page);
			if (rc < 0) {
				LOG_ERR("Error %d while getting page info", rc);
				return rc;
			}
			if (page.size != ctx->page_size) {
				LOG_ERR("Non-uniform page size is not supported");
				return rc;
			}
			offset += page.size;
		}

		if (offset != ctx->offset + ctx->size) {
			LOG_ERR("Last page crossess disk %s boundary",
				ctx->info.name);
			return -EINVAL;
		}
	}

	if (ctx->page_size > ctx->cache_size) {
		LOG_ERR("Cache too small (%zu needs %zu)",
			ctx->cache_size, ctx->page_size);
		return -ENOMEM;
	}

	return 0;
}

static int disk_flash_access_init(struct disk_info *disk)
{
	struct flashdisk_data *ctx;
	const struct flash_area *fap;
	int rc;

	ctx = CONTAINER_OF(disk, struct flashdisk_data, info);

	rc = flash_area_open(ctx->area_id, &fap);
	if (rc < 0) {
		LOG_ERR("Flash area %u open error %d", ctx->area_id, rc);
		return rc;
	}

	k_mutex_lock(&ctx->lock, K_FOREVER);

	disk->dev = flash_area_get_device(fap);

	rc = flashdisk_init_runtime(ctx, fap);
	if (rc < 0) {
		flash_area_close(fap);
	}
	k_mutex_unlock(&ctx->lock);

	return rc;
}

static bool sectors_in_range(struct flashdisk_data *ctx,
			     uint32_t start_sector, uint32_t sector_count)
{
	uint32_t start, end;

	start = ctx->offset + (start_sector * ctx->sector_size);
	end = start + (sector_count * ctx->sector_size);

	if ((end >= start) && (start >= ctx->offset) && (end <= ctx->offset + ctx->size)) {
		return true;
	}

	LOG_ERR("sector start %" PRIu32 " count %" PRIu32
		" outside partition boundary", start_sector, sector_count);
	return false;
}

static int disk_flash_access_read(struct disk_info *disk, uint8_t *buff,
				uint32_t start_sector, uint32_t sector_count)
{
	struct flashdisk_data *ctx;
	off_t fl_addr;
	uint32_t remaining;
	uint32_t offset;
	uint32_t len;
	int rc = 0;

	ctx = CONTAINER_OF(disk, struct flashdisk_data, info);

	if (!sectors_in_range(ctx, start_sector, sector_count)) {
		return -EINVAL;
	}

	fl_addr = ctx->offset + start_sector * ctx->sector_size;
	remaining = (sector_count * ctx->sector_size);

	k_mutex_lock(&ctx->lock, K_FOREVER);

	/* Operate on page addresses to easily check for cached data */
	offset = fl_addr & (ctx->page_size - 1);
	fl_addr = ROUND_DOWN(fl_addr, ctx->page_size);

	/* Read up to page boundary on first iteration */
	len = ctx->page_size - offset;
	while (remaining) {
		if (remaining < len) {
			len = remaining;
		}

		if (ctx->cache_valid && ctx->cached_addr == fl_addr) {
			memcpy(buff, &ctx->cache[offset], len);
		} else if (flash_read(disk->dev, fl_addr + offset, buff, len) < 0) {
			rc = -EIO;
			goto end;
		}

		fl_addr += ctx->page_size;
		remaining -= len;
		buff += len;

		/* Try to read whole page on next iteration */
		len = ctx->page_size;
		offset = 0;
	}

end:
	k_mutex_unlock(&ctx->lock);

	return rc;
}

static int flashdisk_cache_commit(struct flashdisk_data *ctx)
{
	if (!ctx->cache_valid || !ctx->cache_dirty) {
		/* Either no cached data or cache matches flash data */
		return 0;
	}

	if (flash_erase(ctx->info.dev, ctx->cached_addr, ctx->page_size) < 0) {
		return -EIO;
	}

	/* write data to flash */
	if (flash_write(ctx->info.dev, ctx->cached_addr, ctx->cache, ctx->page_size) < 0) {
		return -EIO;
	}

	ctx->cache_dirty = false;
	return 0;
}

static int flashdisk_cache_load(struct flashdisk_data *ctx, off_t fl_addr)
{
	int rc;

	__ASSERT_NO_MSG((fl_addr & (ctx->page_size - 1)) == 0);

	if (ctx->cache_valid) {
		if (ctx->cached_addr == fl_addr) {
			/* Page is already cached */
			return 0;
		}
		/* Different page is in cache, commit it first */
		rc = flashdisk_cache_commit(ctx);
		if (rc < 0) {
			/* Failed to commit dirty page, abort */
			return rc;
		}
	}

	/* Load page into cache */
	ctx->cache_valid = false;
	ctx->cache_dirty = false;
	ctx->cached_addr = fl_addr;
	rc = flash_read(ctx->info.dev, fl_addr, ctx->cache, ctx->page_size);
	if (rc == 0) {
		/* Successfully loaded into cache, mark as valid */
		ctx->cache_valid = true;
		return 0;
	}

	return -EIO;
}

/* input size is either less or equal to a block size (ctx->page_size)
 * and write data never spans across adjacent blocks.
 */
static int flashdisk_cache_write(struct flashdisk_data *ctx, off_t start_addr,
				uint32_t size, const void *buff)
{
	int rc;
	off_t fl_addr;
	uint32_t offset;

	/* adjust offset if starting address is not erase-aligned address */
	offset = start_addr & (ctx->page_size - 1);

	/* always align starting address for flash cache operations */
	fl_addr = ROUND_DOWN(start_addr, ctx->page_size);

	/* when writing full page the address must be page aligned
	 * when writing partial page user data must be within a single page
	 */
	__ASSERT_NO_MSG(fl_addr + ctx->page_size >= start_addr + size);

	rc = flashdisk_cache_load(ctx, fl_addr);
	if (rc < 0) {
		return rc;
	}

	/* Do not mark cache as dirty if data to be written matches cache.
	 * If cache is already dirty, copy data to cache without compare.
	 */
	if (ctx->cache_dirty || memcmp(&ctx->cache[offset], buff, size)) {
		/* Update cache and mark it as dirty */
		memcpy(&ctx->cache[offset], buff, size);
		ctx->cache_dirty = true;
	}

	return 0;
}

static int disk_flash_access_write(struct disk_info *disk, const uint8_t *buff,
				 uint32_t start_sector, uint32_t sector_count)
{
	struct flashdisk_data *ctx;
	off_t fl_addr;
	uint32_t remaining;
	uint32_t size;
	int rc = 0;

	ctx = CONTAINER_OF(disk, struct flashdisk_data, info);

	if (ctx->cache_size == 0) {
		return -ENOTSUP;
	}

	if (!sectors_in_range(ctx, start_sector, sector_count)) {
		return -EINVAL;
	}

	fl_addr = ctx->offset + start_sector * ctx->sector_size;
	remaining = (sector_count * ctx->sector_size);

	k_mutex_lock(&ctx->lock, K_FOREVER);

	/* check if start address is erased-aligned address  */
	if (fl_addr & (ctx->page_size - 1)) {
		off_t block_bnd;

		/* not aligned */
		/* check if the size goes over flash block boundary */
		block_bnd = fl_addr + ctx->page_size;
		block_bnd = block_bnd & ~(ctx->page_size - 1);
		if ((fl_addr + remaining) <= block_bnd) {
			/* not over block boundary (a partial block also) */
			if (flashdisk_cache_write(ctx, fl_addr, remaining, buff) < 0) {
				rc = -EIO;
			}
			goto end;
		}

		/* write goes over block boundary */
		size = GET_SIZE_TO_BOUNDARY(fl_addr, ctx->page_size);

		/* write first partial block */
		if (flashdisk_cache_write(ctx, fl_addr, size, buff) < 0) {
			rc = -EIO;
			goto end;
		}

		fl_addr += size;
		remaining -= size;
		buff += size;
	}

	/* start is an erase-aligned address */
	while (remaining) {
		if (remaining < ctx->page_size) {
			break;
		}

		if (flashdisk_cache_write(ctx, fl_addr, ctx->page_size, buff) < 0) {
			rc = -EIO;
			goto end;
		}

		fl_addr += ctx->page_size;
		remaining -= ctx->page_size;
		buff += ctx->page_size;
	}

	/* remaining partial block */
	if (remaining) {
		if (flashdisk_cache_write(ctx, fl_addr, remaining, buff) < 0) {
			rc = -EIO;
			goto end;
		}
	}

end:
	k_mutex_unlock(&ctx->lock);

	return 0;
}

static int disk_flash_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buff)
{
	int rc;
	struct flashdisk_data *ctx;

	ctx = CONTAINER_OF(disk, struct flashdisk_data, info);

	switch (cmd) {
	case DISK_IOCTL_CTRL_SYNC:
		k_mutex_lock(&ctx->lock, K_FOREVER);
		rc = flashdisk_cache_commit(ctx);
		k_mutex_unlock(&ctx->lock);
		return rc;
	case DISK_IOCTL_GET_SECTOR_COUNT:
		*(uint32_t *)buff = ctx->size / ctx->sector_size;
		return 0;
	case DISK_IOCTL_GET_SECTOR_SIZE:
		*(uint32_t *)buff = ctx->sector_size;
		return 0;
	case DISK_IOCTL_GET_ERASE_BLOCK_SZ: /* in sectors */
		k_mutex_lock(&ctx->lock, K_FOREVER);
		*(uint32_t *)buff = ctx->page_size / ctx->sector_size;
		k_mutex_unlock(&ctx->lock);
		return 0;
	default:
		break;
	}

	return -EINVAL;
}

static const struct disk_operations flash_disk_ops = {
	.init = disk_flash_access_init,
	.status = disk_flash_access_status,
	.read = disk_flash_access_read,
	.write = disk_flash_access_write,
	.ioctl = disk_flash_access_ioctl,
};

#define DT_DRV_COMPAT zephyr_flash_disk

#define PARTITION_PHANDLE(n) DT_PHANDLE_BY_IDX(DT_DRV_INST(n), partition, 0)
/* Force cache size to 0 if partition is read-only */
#define CACHE_SIZE(n) (DT_INST_PROP(n, cache_size) * !DT_PROP(PARTITION_PHANDLE(n), read_only))

#define DEFINE_FLASHDISKS_CACHE(n) \
	static uint8_t __aligned(4) flashdisk##n##_cache[CACHE_SIZE(n)];
DT_INST_FOREACH_STATUS_OKAY(DEFINE_FLASHDISKS_CACHE)

#define DEFINE_FLASHDISKS_DEVICE(n)						\
{										\
	.info = {								\
		.ops = &flash_disk_ops,						\
		.name = DT_INST_PROP(n, disk_name),				\
	},									\
	.area_id = DT_FIXED_PARTITION_ID(PARTITION_PHANDLE(n)),			\
	.offset = DT_REG_ADDR(PARTITION_PHANDLE(n)),				\
	.cache = flashdisk##n##_cache,						\
	.cache_size = sizeof(flashdisk##n##_cache),				\
	.size = DT_REG_SIZE(PARTITION_PHANDLE(n)),				\
	.sector_size = DT_INST_PROP(n, sector_size),				\
},

static struct flashdisk_data flash_disks[] = {
	DT_INST_FOREACH_STATUS_OKAY(DEFINE_FLASHDISKS_DEVICE)
};

#define VERIFY_CACHE_SIZE_IS_NOT_ZERO_IF_NOT_READ_ONLY(n)			\
	COND_CODE_1(DT_PROP(PARTITION_PHANDLE(n), read_only),			\
		(/* cache-size is not used for read-only disks */),		\
		(BUILD_ASSERT(DT_INST_PROP(n, cache_size) != 0,			\
		"Devicetree node " DT_NODE_PATH(DT_DRV_INST(n))			\
		" must have non-zero cache-size");))
DT_INST_FOREACH_STATUS_OKAY(VERIFY_CACHE_SIZE_IS_NOT_ZERO_IF_NOT_READ_ONLY)

#define VERIFY_CACHE_SIZE_IS_MULTIPLY_OF_SECTOR_SIZE(n)					\
	BUILD_ASSERT(DT_INST_PROP(n, cache_size) % DT_INST_PROP(n, sector_size) == 0,	\
		"Devicetree node " DT_NODE_PATH(DT_DRV_INST(n))				\
		" has cache size which is not a multiple of its sector size");
DT_INST_FOREACH_STATUS_OKAY(VERIFY_CACHE_SIZE_IS_MULTIPLY_OF_SECTOR_SIZE)

static int disk_flash_init(const struct device *dev)
{
	ARG_UNUSED(dev);
	int err = 0;

	for (int i = 0; i < ARRAY_SIZE(flash_disks); i++) {
		int rc;

		k_mutex_init(&flash_disks[i].lock);

		rc = disk_access_register(&flash_disks[i].info);
		if (rc < 0) {
			LOG_ERR("Failed to register disk %s error %d",
				flash_disks[i].info.name, rc);
			err = rc;
		}
	}

	return err;
}

SYS_INIT(disk_flash_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
