/*  NVS: non volatile storage in flash
 *
 * Copyright (c) 2018 Laczen
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <flash.h>
#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include <nvs/nvs.h>
#include <crc8.h>
#include "nvs_priv.h"

/* basic routines */
/* _nvs_al_size returns size aligned to fs->write_block_size */
static inline size_t _nvs_al_size(struct nvs_fs *fs, size_t len)
{
	if (fs->write_block_size <= 1) {
		return len;
	}
	return (len + (fs->write_block_size - 1)) & ~(fs->write_block_size - 1);
}
/* end basic routines */

/* flash routines */
/* basic aligned flash write to nvs address */
static int _nvs_flash_al_wrt(struct nvs_fs *fs, u32_t addr, const void *data,
		      size_t len)
{
	int rc;
	off_t offset;
	size_t blen;
	u8_t buf[fs->write_block_size];

	offset = fs->offset;
	offset += fs->sector_size * (addr >> ADDR_SECT_SHIFT);
	offset += addr & ADDR_OFFS_MASK;

	rc = flash_write_protection_set(fs->flash_device, 0);
	if (rc) {
		/* flash protection set error */
		return rc;
	}
	blen = len & ~(fs->write_block_size);
	rc = flash_write(fs->flash_device, offset, data, blen);
	if (rc) {
		/* flash write error */
		return rc;
	}
	len -= blen;
	offset += blen;
	data += blen;
	if (len) {
		memcpy(buf, data, len);
		memset(buf + len, 0xff, fs->write_block_size - len);
		rc = flash_write(fs->flash_device, offset, buf,
				 fs->write_block_size);
		if (rc) {
			/* flash write error */
			return rc;
		}
	}
	(void) flash_write_protection_set(fs->flash_device, 1);
	return 0;
}

/* basic flash read from nvs address */
static int _nvs_flash_rd(struct nvs_fs *fs, u32_t addr, void *data,
		  size_t len)
{
	int rc;
	off_t offset;

	offset = fs->offset;
	offset += fs->sector_size * (addr >> ADDR_SECT_SHIFT);
	offset += addr & ADDR_OFFS_MASK;

	rc = flash_read(fs->flash_device, offset, data, len);
	return rc;

}

/* allocation entry write */
static int _nvs_flash_ate_wrt(struct nvs_fs *fs, const struct nvs_ate *entry)
{
	int rc;

	rc = _nvs_flash_al_wrt(fs, fs->ate_wra, entry,
			       sizeof(struct nvs_ate));
	fs->ate_wra -= _nvs_al_size(fs, sizeof(struct nvs_ate));

	return rc;
}

/* data write */
static int _nvs_flash_data_wrt(struct nvs_fs *fs, const void *data, size_t len)
{
	int rc;

	rc = _nvs_flash_al_wrt(fs, fs->data_wra, data, len);
	fs->data_wra += _nvs_al_size(fs, len);

	return rc;
}

/* flash ate read */
static int _nvs_flash_ate_rd(struct nvs_fs *fs, u32_t addr,
			     struct nvs_ate *entry)
{
	return _nvs_flash_rd(fs, addr, entry, sizeof(struct nvs_ate));
}

/* end of basic flash routines */

/* advanced flash routines */

/* _nvs_flash_block_cmp compares the data in flash at addr to data
 * in blocks of size NVS_BLOCK_SIZE aligned to fs->write_block_size
 * returns 0 if equal, 1 if not equal, errcode if error
 */
static int _nvs_flash_block_cmp(struct nvs_fs *fs, u32_t addr, const void *data,
			 size_t len)
{
	int rc;
	size_t bytes_to_cmp, block_size;
	u8_t buf[NVS_BLOCK_SIZE];

	block_size = NVS_BLOCK_SIZE & ~(fs->write_block_size - 1);
	while (len) {
		bytes_to_cmp = min(block_size, len);
		rc = _nvs_flash_rd(fs, addr, buf, bytes_to_cmp);
		if (rc) {
			return rc;
		}
		rc = memcmp(data, buf, bytes_to_cmp);
		if (rc) {
			return 1;
		}
		len -= bytes_to_cmp;
		addr += bytes_to_cmp;
		data += bytes_to_cmp;
	}
	return 0;
}

/* _nvs_flash_cmp_const compares the data in flash at addr to a constant
 * value. returns 0 if all data in flash is equal to value, 1 if not equal,
 * errcode if error
 */
static int _nvs_flash_cmp_const(struct nvs_fs *fs, u32_t addr, u8_t value,
			       size_t len)
{
	int rc;
	size_t bytes_to_cmp, block_size;
	u8_t cmp[NVS_BLOCK_SIZE];

	block_size = NVS_BLOCK_SIZE & ~(fs->write_block_size - 1);
	memset(cmp, value, block_size);
	while (len) {
		bytes_to_cmp = min(block_size, len);
		rc = _nvs_flash_block_cmp(fs, addr, cmp, bytes_to_cmp);
		if (rc) {
			return rc;
		}
		len -= bytes_to_cmp;
		addr += bytes_to_cmp;
	}
	return 0;
}

/* flash block move: move a block at addr to the current data write location
 * and updates the data write location.
 */
static int _nvs_flash_block_move(struct nvs_fs *fs, u32_t addr, size_t len)
{
	int rc;
	size_t bytes_to_copy, block_size;
	u8_t buf[NVS_BLOCK_SIZE];

	block_size = NVS_BLOCK_SIZE & ~(fs->write_block_size - 1);

	while (len) {
		bytes_to_copy =	min(block_size, len);
		rc = _nvs_flash_rd(fs, addr, buf, bytes_to_copy);
		if (rc) {
			return rc;
		}
		rc = _nvs_flash_data_wrt(fs, buf, bytes_to_copy);
		if (rc) {
			return rc;
		}
		len -= bytes_to_copy;
		addr += bytes_to_copy;
	}
	return 0;
}

/* erase a sector by first checking it is used and then erasing if required
 * return 0 if OK, errorcode on error.
 */
static int _nvs_flash_erase_sector(struct nvs_fs *fs, u32_t addr)
{
	int rc;
	off_t offset;

	addr &= ADDR_SECT_MASK;
	rc = _nvs_flash_cmp_const(fs, addr, 0xff, fs->sector_size);
	if (rc <= 0) {
		/* flash error or empty sector */
		return rc;
	}

	offset = fs->offset;
	offset += fs->sector_size * (addr >> ADDR_SECT_SHIFT);

	rc = flash_write_protection_set(fs->flash_device, 0);
	if (rc) {
		/* flash protection set error */
		return rc;
	}
	SYS_LOG_DBG("Erasing flash at %"PRIx32", len %d",
		    offset, fs->sector_size);
	rc = flash_erase(fs->flash_device, offset, fs->sector_size);
	if (rc) {
		/* flash erase error */
		return rc;
	}
	(void) flash_write_protection_set(fs->flash_device, 1);
	return 0;
}

/* crc update on allocation entry */
static void _nvs_ate_crc8_update(struct nvs_ate *entry)
{
	u8_t crc8;

	entry->crc8 = 0xff;
	crc8 = crc8_ccitt(0xff, entry, sizeof(struct nvs_ate));
	entry->crc8 = crc8;
}

/* crc check on allocation entry
 * returns 0 if OK, 1 on crc fail
 */
static int _nvs_ate_crc8_check(struct nvs_ate *entry)
{
	u8_t crc8;

	crc8 = entry->crc8;
	_nvs_ate_crc8_update(entry);
	if (crc8 == entry->crc8) {
		return 0;
	}
	/* set back the original crc8 if different */
	entry->crc8 = crc8;
	return 1;
}

/* store an entry in flash */
static int _nvs_flash_wrt_entry(struct nvs_fs *fs, u16_t id, const void *data,
			size_t len)
{
	int rc;
	struct nvs_ate entry;
	size_t ate_size;

	ate_size = _nvs_al_size(fs, sizeof(struct nvs_ate));

	entry.id = id;
	entry.offset = (u16_t)(fs->data_wra & ADDR_OFFS_MASK);
	entry.len = (u16_t)len;
	entry.part = 0xff;

	_nvs_ate_crc8_update(&entry);

	rc = _nvs_flash_data_wrt(fs, data, len);
	if (rc) {
		return rc;
	}
	rc = _nvs_flash_ate_wrt(fs, &entry);
	if (rc) {
		return rc;
	}

	if (len != 0) {
		fs->free_space -= _nvs_al_size(fs, len);
		fs->free_space -= ate_size;
	}
	return 0;
}
/* end of flash routines */

/* walking through allocation entry list, from newest to oldest entries
 * read ate from addr, modify addr to the previous ate
 */
static int _nvs_prev_ate(struct nvs_fs *fs, u32_t *addr, struct nvs_ate *ate)
{
	int rc;
	size_t ate_size;

	ate_size = _nvs_al_size(fs, sizeof(struct nvs_ate));

	rc = _nvs_flash_ate_rd(fs, *addr, ate);
	if (rc) {
		return rc;
	}

	while (1) {
		*addr += ate_size;
		if (((*addr) & ADDR_OFFS_MASK) != fs->sector_size)  {
			break;
		}
		/* last ate in sector, do jump to previous sector */
		if (((*addr) >> ADDR_SECT_SHIFT) == 0) {
			*addr += (fs->sector_count << ADDR_SECT_SHIFT);
		}
		(*addr) -= (1 << ADDR_SECT_SHIFT);
		while (1) {
			*addr -= ate_size;
			rc = _nvs_flash_cmp_const(fs, *addr, 0xff, ate_size);
			if (!rc) {
				break;
			}
			rc = _nvs_flash_cmp_const(fs, *addr, 0x00, ate_size);
			if (!rc) {
				break;
			}
		}
		/* stop after stepping through all sectors */
		if (*addr == fs->ate_wra) {
			break;
		}
	}
	return 0;
}

static void _nvs_sector_advance(struct nvs_fs *fs, u32_t *addr)
{
	*addr += (1 << ADDR_SECT_SHIFT);
	if ((*addr >> ADDR_SECT_SHIFT) == fs->sector_count) {
		*addr -= (fs->sector_count << ADDR_SECT_SHIFT);
	}
}

/* allocation entry close (this closes the current sector) by writing all
 * zeros at fs->ate_wra.
 */
static int _nvs_sector_close(struct nvs_fs *fs)
{
	int rc;
	u8_t buf[sizeof(struct nvs_ate)];
	size_t ate_size;

	ate_size = sizeof(struct nvs_ate);

	memset(buf, 0, ate_size);

	rc = _nvs_flash_al_wrt(fs, fs->ate_wra, buf, ate_size);
	if (rc) {
		return rc;
	}

	fs->ate_wra &= ADDR_SECT_MASK;
	fs->ate_wra += (fs->sector_size - ate_size);
	_nvs_sector_advance(fs, &fs->ate_wra);

	fs->data_wra = fs->ate_wra & ADDR_SECT_MASK;

	return 0;
}


/* garbage collection: the address ate_wra has been updated to the new sector
 * that has just been started. The data to gc is in the sector after this new
 * sector.
 */
static int _nvs_gc(struct nvs_fs *fs)
{
	int rc;
	struct nvs_ate gc_ate, wlk_ate;
	u32_t gc_addr, wlk_addr, wlk_prev_addr, data_addr, sec_addr;
	size_t ate_size;

	ate_size = _nvs_al_size(fs, sizeof(struct nvs_ate));

	gc_addr = (fs->ate_wra & ADDR_SECT_MASK) + fs->sector_size - ate_size;
	_nvs_sector_advance(fs, &gc_addr);
	sec_addr = gc_addr;

	while (1) {
		/* if the sector is empty don't do gc */
		rc = _nvs_flash_cmp_const(fs, gc_addr, 0xff, ate_size);
		if (!rc) {
			break;
		}
		/* if sector end is reached stop gc */
		rc = _nvs_flash_cmp_const(fs, gc_addr, 0x00, ate_size);
		if (!rc) {
			break;
		}
		rc = _nvs_flash_ate_rd(fs, gc_addr, &gc_ate);
		if (rc) {
			return rc;
		}
		wlk_addr = fs->ate_wra;
		while (1) {
			wlk_prev_addr = wlk_addr;
			rc = _nvs_prev_ate(fs, &wlk_addr, &wlk_ate);
			if (rc) {
				return rc;
			}
			/* if ate with same id is reached and it has valid crc8
			 * we might need to copy.
			 */
			if ((wlk_ate.id == gc_ate.id) &&
			    (!_nvs_ate_crc8_check(&wlk_ate))) {
				break;
			}
		}
		/* if walk has reached the same address as gc_addr copy is
		 * needed unless it is a deleted item.
		 */
		if ((wlk_prev_addr == gc_addr) && gc_ate.len) {
			/* copy needed */
			SYS_LOG_DBG("Moving %d, len %d", gc_ate.id, gc_ate.len);

			data_addr = (gc_addr & ADDR_SECT_MASK);
			data_addr += gc_ate.offset;

			gc_ate.offset = (u16_t)(fs->data_wra & ADDR_OFFS_MASK);
			_nvs_ate_crc8_update(&gc_ate);

			rc = _nvs_flash_block_move(fs, data_addr, gc_ate.len);
			if (rc) {
				return rc;
			}

			rc = _nvs_flash_ate_wrt(fs, &gc_ate);
			if (rc) {
				return rc;
			}
		}
		gc_addr -= ate_size;
	}
	rc = _nvs_flash_erase_sector(fs, sec_addr);
	if (rc) {
		return rc;
	}
	return 0;
}

static int _nvs_update_free_space(struct nvs_fs *fs)
{

	int rc;
	struct nvs_ate step_ate, wlk_ate;
	u32_t step_addr, wlk_addr;
	size_t ate_size;

	ate_size = _nvs_al_size(fs, sizeof(struct nvs_ate));

	fs->free_space = 0;
	for (u16_t i = 1; i < fs->sector_count; i++) {
		fs->free_space += (fs->sector_size - ate_size);
	}

	step_addr = fs->ate_wra;

	while (1) {
		rc = _nvs_prev_ate(fs, &step_addr, &step_ate);
		if (rc) {
			return rc;
		}

		wlk_addr = fs->ate_wra;

		while (1) {
			rc = _nvs_prev_ate(fs, &wlk_addr, &wlk_ate);
			if (rc) {
				return rc;
			}
			if ((wlk_ate.id == step_ate.id) ||
			    (wlk_addr == fs->ate_wra)) {
				break;
			}

		}

		if ((wlk_addr == step_addr) && step_ate.len &&
		    (!_nvs_ate_crc8_check(&step_ate))) {
			/* count needed */
			fs->free_space -= _nvs_al_size(fs, step_ate.len);
			fs->free_space -= ate_size;
		}

		if (step_addr == fs->ate_wra) {
			break;
		}

	}
	return 0;
}

int nvs_clear(struct nvs_fs *fs)
{
	int rc;
	off_t addr;

	for (u16_t i = 0; i < fs->sector_count; i++) {
		addr = i << ADDR_SECT_SHIFT;
		rc = _nvs_flash_erase_sector(fs, addr);
		if (rc) {
			return rc;
		}
	}
	return 0;
}

int nvs_reinit(struct nvs_fs *fs)
{
	int rc;
	size_t ate_size, empty_len;
	struct nvs_ate ate;
	u32_t addr;


	k_mutex_lock(&fs->nvs_lock, K_FOREVER);

	ate_size = _nvs_al_size(fs, sizeof(struct nvs_ate));

	/* step through the sectors to find the last sector */
	for (u16_t i = 0; i < fs->sector_count; i++) {
		addr = (i << ADDR_SECT_SHIFT) + fs->sector_size - ate_size;
		fs->ate_wra = addr;
		rc = _nvs_prev_ate(fs, &addr, &ate);
		if (rc) {
			goto end;
		}
		rc = _nvs_flash_cmp_const(fs, addr - ate_size, 0x00, ate_size);
		if (!rc) {
			/* we are just before (or after) sector end */
			continue;
		}
		rc = _nvs_flash_cmp_const(fs, addr - ate_size, 0xff, ate_size);
		if (!rc) {
			break;
		}
	}

	fs->ate_wra = addr;
	fs->data_wra = addr & ADDR_SECT_MASK;

	/* Normally addr points to a location that does not contain all ff, so
	 * ate_size needs to be substracted to get ate_wra. However there is an
	 * exception, when addr is the very end of a sector; then we keep
	 * fs->ate_wra.
	 */
	rc = _nvs_flash_cmp_const(fs, addr, 0xff, ate_size);
	if (rc < 0) {
		goto end;
	}
	if (rc) {
		/* fs->ate_wra not at sector end */
		fs->ate_wra -= ate_size;
		rc = _nvs_flash_ate_rd(fs, addr, &ate);
		if (rc) {
			goto end;
		}
		if (!_nvs_ate_crc8_check(&ate)) {
		/* crc8 is ok, complete write of ate was performed */
			fs->data_wra += ate.offset;
			fs->data_wra += _nvs_al_size(fs, ate.len);
		}
	}

	/* possible data write after last ate write, update data_wra */
	while (1) {
		empty_len = fs->ate_wra - fs->data_wra;
		if (!empty_len) {
			break;
		}
		rc = _nvs_flash_cmp_const(fs, fs->data_wra, 0xff, empty_len);
		if (rc < 0) {
			goto end;
		}
		if (!rc) {
			break;
		}
		fs->data_wra += fs->write_block_size;
	}

	/* if the sector after the write sector is not empty gc was interrupted
	 * we need to restart gc, first erase the sector before restarting gc
	 * otherwise the data may not fit into the sector.
	 */
	addr = fs->ate_wra & ADDR_SECT_MASK;
	_nvs_sector_advance(fs, &addr);
	rc = _nvs_flash_cmp_const(fs, addr, 0xff, fs->sector_size);
	if (rc < 0) {
		goto end;
	}
	if (rc) {
		/* the sector after fs->ate_wrt is not empty */
		rc = _nvs_flash_erase_sector(fs, fs->ate_wra);
		if (rc) {
			goto end;
		}
		fs->ate_wra &= ADDR_SECT_MASK;
		fs->ate_wra += (fs->sector_size - ate_size);
		fs->data_wra = (fs->ate_wra & ADDR_SECT_MASK);
		rc = _nvs_gc(fs);
		if (rc) {
			goto end;
		}
	}

	rc = _nvs_update_free_space(fs);

end:
	k_mutex_unlock(&fs->nvs_lock);
	return rc;
}

int nvs_init(struct nvs_fs *fs, const char *dev_name)
{

	int rc;

	k_mutex_init(&fs->nvs_lock);

	fs->flash_device = device_get_binding(dev_name);
	if (!fs->flash_device) {
		SYS_LOG_ERR("No valid flash device found");
		return -ENXIO;
	}

	fs->write_block_size = flash_get_write_block_size(fs->flash_device);

	/* check the number of sectors, it should be at least 2 */
	if (fs->sector_count < 2) {
		SYS_LOG_ERR("Configuration error - sector count");
		return -EINVAL;
	}

	fs->locked = false;
	rc = nvs_reinit(fs);
	if (rc) {
		return rc;
	}

	SYS_LOG_INF("%d Sectors of %d byte", fs->sector_count, fs->sector_size);
	SYS_LOG_INF("alloc wra: %d-%"PRIx32"",
		    (fs->ate_wra >> ADDR_SECT_SHIFT),
		    (fs->ate_wra & ADDR_OFFS_MASK));
	SYS_LOG_INF("data wra: %d-%"PRIx32"",
		    (fs->data_wra >> ADDR_SECT_SHIFT),
		    (fs->data_wra & ADDR_OFFS_MASK));
	SYS_LOG_INF("Free space: %d", fs->free_space);

	return 0;
}

ssize_t nvs_write(struct nvs_fs *fs, u16_t id, const void *data, size_t len)
{
	int rc, gc_count;
	size_t ate_size, data_size;
	struct nvs_ate wlk_ate;
	u32_t wlk_addr, rd_addr, freed_space;
	u16_t sector_freespace;

	ate_size = _nvs_al_size(fs, sizeof(struct nvs_ate));
	data_size = _nvs_al_size(fs, len);


	if ((len > (fs->sector_size - 2*ate_size)) ||
	    ((len > 0) && (data == NULL))) {
		return -EINVAL;
	}

	if (fs->locked) {
		return -EROFS;
	}

	/* find latest entry with same id */
	wlk_addr = fs->ate_wra;
	rd_addr = wlk_addr;
	freed_space = 0;

	while (1) {
		rd_addr = wlk_addr;
		rc = _nvs_prev_ate(fs, &wlk_addr, &wlk_ate);
		if (rc) {
			return rc;
		}
		if ((wlk_ate.id == id) && (!_nvs_ate_crc8_check(&wlk_ate))) {
			break;
		}
		if (wlk_addr == fs->ate_wra) {
			break;
		}
	}

	if (wlk_addr != fs->ate_wra) {
		/* previous entry found */
		rd_addr &= ADDR_SECT_MASK;
		rd_addr += wlk_ate.offset;

		if (len == 0) {
			/* do not try to compare with empty data */
			if (wlk_ate.len == 0) {
				return 0;
			}
		} else {
			/* compare the data and if equal return 0 */
			rc = _nvs_flash_block_cmp(fs, rd_addr, data, len);
			if (rc <= 0) {
				return rc;
			}
		}
		/* data different, calculate freed space */
		freed_space = _nvs_al_size(fs, wlk_ate.len);
		freed_space += ate_size;
	}

	k_mutex_lock(&fs->nvs_lock, K_FOREVER);

	fs->free_space += freed_space;
	if (fs->free_space < (data_size + ate_size)) {
		rc = -ENOSPC;
		goto end;
	}

	gc_count = 0;
	while (1) {
		if (gc_count == fs->sector_count) {
			rc = -EROFS;
			goto end;
		}
		sector_freespace = fs->ate_wra - fs->data_wra;
		if (sector_freespace >= data_size + ate_size) {
			rc = _nvs_flash_wrt_entry(fs, id, data, len);
			if (rc) {
				goto end;
			}
			break;
		}
		rc = _nvs_sector_close(fs);
		if (rc) {
			goto end;
		}
		rc = _nvs_gc(fs);
		if (rc) {
			goto end;
		}
		gc_count++;
	}
	rc = len;
end:
	k_mutex_unlock(&fs->nvs_lock);
	if (rc < 0) {
		fs->free_space -= freed_space;
	}
	if (rc == -EROFS) {
		fs->locked = true;
	}
	return rc;
}

int nvs_delete(struct nvs_fs *fs, u16_t id)
{
	return nvs_write(fs, id, NULL, 0);
}

ssize_t nvs_read_hist(struct nvs_fs *fs, u16_t id, void *data, size_t len,
		  u16_t cnt)
{
	int rc;
	u32_t wlk_addr, rd_addr;
	u16_t cnt_his;
	struct nvs_ate wlk_ate;
	size_t ate_size;

	ate_size = _nvs_al_size(fs, sizeof(struct nvs_ate));

	if (len > (fs->sector_size - 2*ate_size)) {
		return -EINVAL;
	}

	cnt_his = 0;

	wlk_addr = fs->ate_wra;
	rd_addr = wlk_addr;

	while (cnt_his <= cnt) {
		rd_addr = wlk_addr;
		rc = _nvs_prev_ate(fs, &wlk_addr, &wlk_ate);
		if (rc) {
			goto err;
		}
		if ((wlk_ate.id == id) &&  (!_nvs_ate_crc8_check(&wlk_ate))) {
			cnt_his++;
		}
		if (wlk_addr == fs->ate_wra) {
			break;
		}
	}

	if (((wlk_addr == fs->ate_wra) && (wlk_ate.id != id)) ||
	    (wlk_ate.len == 0) || (cnt_his < cnt)) {
		return -ENOENT;
	}

	rd_addr &= ADDR_SECT_MASK;
	rd_addr += wlk_ate.offset;
	rc = _nvs_flash_rd(fs, rd_addr, data, min(len, wlk_ate.len));
	if (rc) {
		goto err;
	}

	return wlk_ate.len;

err:
	return rc;
}

ssize_t nvs_read(struct nvs_fs *fs, u16_t id, void *data, size_t len)
{
	int rc;

	rc = nvs_read_hist(fs, id, data, len, 0);
	return rc;
}
