/*
 * 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 <crc.h>
#include <misc/__assert.h>
#include <misc/printk.h>
#include <nffs/os.h>
#include <nffs/nffs.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;

/* nffs flash area descriptors */
static struct nffs_area_desc descs[CONFIG_NFFS_FILESYSTEM_MAX_AREAS + 1];

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, match_len;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	zfp->filep = NULL;

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

	match_len = strlen(zfp->mp->mnt_point);
	rc = nffs_file_open((struct nffs_file **)&zfp->filep, &file_name[match_len],
			    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->filep);
	if (!rc) {
		zfp->filep = NULL;
	}

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

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

	k_mutex_lock(&nffs_lock, K_FOREVER);

	match_len = strlen(mountp->mnt_point);
	rc = nffs_path_unlink(&path[match_len]);

	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->filep, 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->filep, 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 = ((struct nffs_file *)zfp->filep)->nf_offset + offset;
		break;
	case FS_SEEK_END:
		rc = nffs_inode_data_len(((struct nffs_file *)zfp->filep)->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->filep, 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->filep) {
		k_mutex_unlock(&nffs_lock);
		return -EIO;
	}

	offset = ((struct nffs_file *)zfp->filep)->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, match_len;

	k_mutex_lock(&nffs_lock, K_FOREVER);

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

	match_len = strlen(mountp->mnt_point);
	rc = nffs_path_new_dir(&path[match_len], NULL);

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

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

	k_mutex_lock(&nffs_lock, K_FOREVER);

	zdp->dirp = NULL;

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

	match_len = strlen(zdp->mp->mnt_point);
	rc = nffs_dir_open(&path[match_len], (struct nffs_dir **)&zdp->dirp);

	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->dirp, &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->dirp);
	if (!rc) {
		zdp->dirp = 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, match_len;

	k_mutex_lock(&nffs_lock, K_FOREVER);

	match_len = strlen(mountp->mnt_point);
	nffs_path_parser_new(&parser, &path[match_len]);

	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, match_len;

	k_mutex_lock(&nffs_lock, K_FOREVER);

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

	match_len = strlen(mountp->mnt_point);
	rc = nffs_path_rename(&from[match_len], &to[match_len]);

	k_mutex_unlock(&nffs_lock);

	return translate_error(rc);
}

static int nffs_mount(struct fs_mount_t *mountp)
{
	struct nffs_flash_desc *flash_desc =
				(struct nffs_flash_desc *)mountp->fs_data;
	int cnt;
	int rc;

	/* Set flash device */
	flash_dev = (struct device *)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);
