/*  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 - 1);
	if (blen > 0) {
		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;
}
