/*
 * Copyright (c) 2017 Codecoup
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdio.h>
#include <string.h>
#include <zephyr/types.h>
#include <errno.h>
#include <init.h>
#include <flash.h>
#include <fs.h>
#include <crc16.h>
#include <misc/__assert.h>
#include <misc/printk.h>
#include <nffs/os.h>

#define NFFS_MAX_FILE_NAME 256

/*
 * NFFS code keeps fs state in RAM but access to these structures is not
 * thread-safe - we need global lock for each fs operation to guarantee two
 * threads won't modify NFFS at the same time.
 */
static struct k_mutex nffs_lock;

/*
 * TODO: Get rid of global flash_dev which limits
 * system to have multiple instances of NFFS.
 */
static struct device *flash_dev;

K_MEM_SLAB_DEFINE(nffs_file_pool,		sizeof(struct nffs_file),
		  CONFIG_FS_NFFS_NUM_FILES,		4);
K_MEM_SLAB_DEFINE(nffs_dir_pool,		sizeof(struct nffs_dir),
		  CONFIG_FS_NFFS_NUM_DIRS,		4);
K_MEM_SLAB_DEFINE(nffs_inode_entry_pool,	sizeof(struct nffs_inode_entry),
		  CONFIG_FS_NFFS_NUM_INODES,		4);
K_MEM_SLAB_DEFINE(nffs_block_entry_pool,	sizeof(struct nffs_hash_entry),
		  CONFIG_FS_NFFS_NUM_BLOCKS,		4);
K_MEM_SLAB_DEFINE(nffs_cache_inode_pool,	sizeof(struct nffs_cache_inode),
		  CONFIG_FS_NFFS_NUM_CACHE_INODES,	4);
K_MEM_SLAB_DEFINE(nffs_cache_block_pool,	sizeof(struct nffs_cache_block),
		  CONFIG_FS_NFFS_NUM_CACHE_BLOCKS,	4);

static int translate_error(int error)
{
	switch (error) {
	case FS_EOK:
		return 0;
	case FS_ECORRUPT:
	case FS_EHW:
		return -EIO;
	case FS_EOFFSET:
	case FS_EINVAL:
		return -EINVAL;
	case FS_ENOMEM:
		return -ENOMEM;
	case FS_ENOENT:
		return -ENOENT;
	case FS_EEMPTY:
		return -ENODEV;
	case FS_EFULL:
		return -ENOSPC;
	case FS_EUNEXP:
	case FS_EOS:
		return -EIO;
	case FS_EEXIST:
		return -EEXIST;
	case FS_EACCESS:
		return -EACCES;
	case FS_EUNINIT:
		return -EIO;
	}

	return -EIO;
}

int nffs_os_mempool_init(void)
{
	/*
	 * Just reinitialize slabs here - this is what original implementation
	 * does. We assume all references to previously allocated blocks, if
	 * any, are invalidated in NFFS code already.
	 */

	k_mem_slab_init(&nffs_file_pool, _k_mem_slab_buf_nffs_file_pool,
			sizeof(struct nffs_file),
			CONFIG_FS_NFFS_NUM_FILES);
	k_mem_slab_init(&nffs_dir_pool, _k_mem_slab_buf_nffs_dir_pool,
			sizeof(struct nffs_dir),
			CONFIG_FS_NFFS_NUM_DIRS);
	k_mem_slab_init(&nffs_inode_entry_pool,
			_k_mem_slab_buf_nffs_inode_entry_pool,
			sizeof(struct nffs_inode_entry),
			CONFIG_FS_NFFS_NUM_INODES);
	k_mem_slab_init(&nffs_block_entry_pool,
			_k_mem_slab_buf_nffs_block_entry_pool,
			sizeof(struct nffs_hash_entry),
			CONFIG_FS_NFFS_NUM_BLOCKS);
	k_mem_slab_init(&nffs_cache_inode_pool,
			_k_mem_slab_buf_nffs_cache_inode_pool,
			sizeof(struct nffs_cache_inode),
			CONFIG_FS_NFFS_NUM_CACHE_INODES);
	k_mem_slab_init(&nffs_cache_block_pool,
			_k_mem_slab_buf_nffs_cache_block_pool,
			sizeof(struct nffs_cache_block),
			CONFIG_FS_NFFS_NUM_CACHE_BLOCKS);

	return 0;
}

void *nffs_os_mempool_get(nffs_os_mempool_t *pool)
{
	int rc;
	void *ptr;

	rc = k_mem_slab_alloc(pool, &ptr, K_NO_WAIT);
	if (rc) {
		ptr = NULL;
	}

	return ptr;
}

int nffs_os_mempool_free(nffs_os_mempool_t *pool, void *block)
{
	k_mem_slab_free(pool, &block);

	return 0;
}

int nffs_os_flash_read(uint8_t id, uint32_t address, void *dst,
		uint32_t num_bytes)
{
	int rc;

	rc = flash_read(flash_dev, address, dst, num_bytes);

	return rc;
}

int nffs_os_flash_write(uint8_t id, uint32_t address, const void *src,
		uint32_t num_bytes)
{
	int rc;

	rc = flash_write_protection_set(flash_dev, false);
	if (rc) {
		return rc;
	}

	rc = flash_write(flash_dev, address, src, num_bytes);

	/* Ignore errors here - this does not affect write operation */
	(void) flash_write_protection_set(flash_dev, true);

	return rc;
}

int nffs_os_flash_erase(uint8_t id, uint32_t address, uint32_t num_bytes)
{
	int rc;

	rc = flash_write_protection_set(flash_dev, false);
	if (rc) {
		return rc;
	}

	rc = flash_erase(flash_dev, address, num_bytes);

	/* Ignore errors here - this does not affect erase operation */
	(void) flash_write_protection_set(flash_dev, true);

	return rc;
}

int nffs_os_flash_info(uint8_t id, uint32_t sector, uint32_t *address,
		uint32_t *size)
{
	struct flash_pages_info pi;
	int rc;

	rc = flash_get_page_info_by_idx(flash_dev, sector, &pi);
	__ASSERT(rc == 0, "Failed to obtain flash page data");

	*address = pi.start_offset;
	*size = pi.size;

	return 0;
}

uint16_t nffs_os_crc16_ccitt(uint16_t initial_crc, const void *buf, int len,
		int final)
{
	return crc16(buf, len, 0x1021, initial_crc, final);
}

static int inode_to_dirent(struct nffs_inode_entry *inode,
			   struct fs_dirent *entry)
{
	u8_t name_len;
	uint32_t size;
	int rc;

	rc = nffs_inode_read_filename(inode, sizeof(entry->name), entry->name,
				      &name_len);
	if (rc) {
		return rc;
	}

	if (nffs_hash_id_is_dir(inode->nie_hash_entry.nhe_id)) {
		entry->type = FS_DIR_ENTRY_DIR;
		entry->size = 0;
	} else {
		entry->type = FS_DIR_ENTRY_FILE;
		nffs_inode_data_len(inode, &size);
		entry->size = size;
	}

	return rc;
}

static int nffs_open(struct fs_file_t *zfp, const char *file_name)
{
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	zfp->nffs_fp = NULL;

	if (!nffs_misc_ready()) {
		k_mutex_unlock(&nffs_lock);
		return -ENODEV;
	}

	rc = nffs_file_open(&zfp->nffs_fp, file_name,
			    FS_ACCESS_READ | FS_ACCESS_WRITE);

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

static int nffs_close(struct fs_file_t *zfp)
{
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	rc = nffs_file_close(zfp->nffs_fp);
	if (!rc) {
		zfp->nffs_fp = NULL;
	}

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

static int nffs_unlink(struct fs_mount_t *mountp, const char *path)
{
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	rc = nffs_path_unlink(path);

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

static ssize_t nffs_read(struct fs_file_t *zfp, void *ptr, size_t size)
{
	uint32_t br;
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	rc = nffs_file_read(zfp->nffs_fp, size, ptr, &br);

	k_mutex_unlock(&nffs_lock);

	if (rc) {
		return translate_error(rc);
	}

	return br;
}

static ssize_t nffs_write(struct fs_file_t *zfp, const void *ptr, size_t size)
{
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	rc = nffs_write_to_file(zfp->nffs_fp, ptr, size);

	k_mutex_unlock(&nffs_lock);

	if (rc) {
		return translate_error(rc);
	}

	/* We need to assume all bytes were written */
	return size;
}

static int nffs_seek(struct fs_file_t *zfp, off_t offset, int whence)
{
	uint32_t len;
	u32_t pos;
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	switch (whence) {
	case FS_SEEK_SET:
		pos = offset;
		break;
	case FS_SEEK_CUR:
		pos = zfp->nffs_fp->nf_offset + offset;
		break;
	case FS_SEEK_END:
		rc = nffs_inode_data_len(zfp->nffs_fp->nf_inode_entry, &len);
		if (rc) {
			k_mutex_unlock(&nffs_lock);
			return -EINVAL;
		}
		pos = len + offset;
		break;
	default:
		k_mutex_unlock(&nffs_lock);
		return -EINVAL;
	}

	rc = nffs_file_seek(zfp->nffs_fp, pos);

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

static off_t nffs_tell(struct fs_file_t *zfp)
{
	u32_t offset;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	if (!zfp->nffs_fp) {
		k_mutex_unlock(&nffs_lock);
		return -EIO;
	}

	offset = zfp->nffs_fp->nf_offset;

	k_mutex_unlock(&nffs_lock);

	return offset;
}

static int nffs_truncate(struct fs_file_t *zfp, off_t length)
{
	/*
	 * FIXME:
	 * There is no API in NFFS to truncate opened file. For now we return
	 * ENOTSUP, but this should be revisited if truncation is implemented
	 * in NFFS at some point.
	 */

	return -ENOTSUP;
}

static int nffs_sync(struct fs_file_t *zfp)
{
	/*
	 * Files are written to flash immediately so we do not need to support
	 * sync call - just return success.
	 */

	return 0;
}

static int nffs_mkdir(struct fs_mount_t *mountp, const char *path)
{
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	if (!nffs_misc_ready()) {
		k_mutex_unlock(&nffs_lock);
		return -ENODEV;
	}

	rc = nffs_path_new_dir(path, NULL);

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

static int nffs_opendir(struct fs_dir_t *zdp, const char *path)
{
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	zdp->nffs_dp = NULL;

	if (!nffs_misc_ready()) {
		k_mutex_unlock(&nffs_lock);
		return -ENODEV;
	}

	rc = nffs_dir_open(path, &zdp->nffs_dp);

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

static int nffs_readdir(struct fs_dir_t *zdp, struct fs_dirent *entry)
{
	struct nffs_dirent *dirent;
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	rc = nffs_dir_read(zdp->nffs_dp, &dirent);
	switch (rc) {
	case 0:
		rc = inode_to_dirent(dirent->nde_inode_entry, entry);
		break;
	case FS_ENOENT:
		entry->name[0] = 0;
		rc = 0;
		break;
	default:
		break;
	}

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

static int nffs_closedir(struct fs_dir_t *zdp)
{
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	rc = nffs_dir_close(zdp->nffs_dp);
	if (!rc) {
		zdp->nffs_dp = NULL;
	}

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

static int nffs_stat(struct fs_mount_t *mountp,
		     const char *path, struct fs_dirent *entry)
{
	struct nffs_path_parser parser;
	struct nffs_inode_entry *parent;
	struct nffs_inode_entry *inode;
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	nffs_path_parser_new(&parser, path);

	rc = nffs_path_find(&parser, &inode, &parent);
	if (rc == 0) {
		rc = inode_to_dirent(inode, entry);
	}

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

static int nffs_statvfs(struct fs_mount_t *mountp,
			const char *path, struct fs_statvfs *stat)
{
	/*
	 * FIXME:
	 * There is not API to retrieve such data in NFFS.
	 */

	return -ENOTSUP;
}

static int nffs_rename(struct fs_mount_t *mountp, const char *from,
		       const char *to)
{
	int rc;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	if (!nffs_misc_ready()) {
		k_mutex_unlock(&nffs_lock);
		return -ENODEV;
	}

	rc = nffs_path_rename(from, to);

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

static int nffs_mount(struct fs_mount_t *mountp)
{
	struct nffs_area_desc descs[CONFIG_NFFS_FILESYSTEM_MAX_AREAS + 1];
	struct nffs_flash_desc *flash_desc =
				(struct nffs_flash_desc *)mountp->fs_data;
	int cnt;
	int rc;

	/* Set flash device */
	flash_dev = mountp->storage_dev;

	/* Set flash descriptor fields */
	flash_desc->id = 0;
	flash_desc->sector_count = flash_get_page_count(flash_dev);
	flash_desc->area_offset = FLASH_AREA_STORAGE_OFFSET;
	flash_desc->area_size = FLASH_AREA_STORAGE_SIZE;

	rc = nffs_misc_reset();
	if (rc) {
		return -EIO;
	}

	cnt = CONFIG_NFFS_FILESYSTEM_MAX_AREAS;
	rc = nffs_misc_desc_from_flash_area(flash_desc, &cnt, descs);
	if (rc) {
		return -EIO;
	}

	rc = nffs_restore_full(descs);
	switch (rc) {
	case 0:
		break;
	case FS_ECORRUPT:
		rc = nffs_format_full(descs);
		if (rc) {
			return -EIO;
		}
		break;
	default:
		return -EIO;
	}

	return 0;
}

/* File system interface */
static struct fs_file_system_t nffs_fs = {
	.open = nffs_open,
	.close = nffs_close,
	.read = nffs_read,
	.write = nffs_write,
	.lseek = nffs_seek,
	.tell = nffs_tell,
	.truncate = nffs_truncate,
	.sync = nffs_sync,
	.opendir = nffs_opendir,
	.readdir = nffs_readdir,
	.closedir = nffs_closedir,
	.mount = nffs_mount,
	.unlink = nffs_unlink,
	.rename = nffs_rename,
	.mkdir = nffs_mkdir,
	.stat = nffs_stat,
	.statvfs = nffs_statvfs,
};

static int nffs_init(struct device *dev)
{
	ARG_UNUSED(dev);

	k_mutex_init(&nffs_lock);

	return fs_register(FS_NFFS, &nffs_fs);
}

SYS_INIT(nffs_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
