/*
 * Copyright (c) 2018 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <errno.h>
#include <kernel.h>
#include <limits.h>
#include <posix/pthread.h>
#include <posix/unistd.h>
#include <string.h>

union file_desc {
	struct fs_file_t file;
	struct fs_dir_t	dir;
};

struct posix_fs_desc {
	union file_desc desc;
	bool is_dir;
	bool used;
};

static struct posix_fs_desc desc_array[CONFIG_POSIX_MAX_OPEN_FILES];

static struct fs_dirent fdirent;
static struct dirent pdirent;

static int posix_fs_alloc_fd(union file_desc **ptr, bool is_dir)
{
	int fd;
	unsigned int key = irq_lock();

	for (fd = 0; fd < CONFIG_POSIX_MAX_OPEN_FILES; fd++) {
		if (desc_array[fd].used == false) {
			*ptr = &desc_array[fd].desc;
			desc_array[fd].used = true;
			desc_array[fd].is_dir = is_dir;
			break;
		}
	}
	irq_unlock(key);

	if (fd >= CONFIG_POSIX_MAX_OPEN_FILES) {
		return -1;
	}

	return fd;
}

static int posix_fs_get_ptr(int fd, union file_desc **ptr, bool is_dir)
{
	int rc = 0;
	unsigned int key;

	if (fd < 0 || fd >= CONFIG_POSIX_MAX_OPEN_FILES) {
		return -1;
	}

	key = irq_lock();

	if ((desc_array[fd].used == true) &&
		(desc_array[fd].is_dir == is_dir)) {
		*ptr = &desc_array[fd].desc;
	} else {
		rc = -1;
	}
	irq_unlock(key);

	return rc;
}

static inline void posix_fs_free_ptr(struct posix_fs_desc *ptr)
{
	struct posix_fs_desc *desc = ptr;
	unsigned int key = irq_lock();

	desc->used = false;
	desc->is_dir = false;
	irq_unlock(key);
}

static inline void posix_fs_free_fd(int fd)
{
	posix_fs_free_ptr(&desc_array[fd]);
}

/**
 * @brief Open a file.
 *
 * See IEEE 1003.1
 */
int open(const char *name, int flags)
{
	int rc, fd;
	struct fs_file_t *ptr = NULL;

	ARG_UNUSED(flags);

	fd = posix_fs_alloc_fd((union file_desc **)&ptr, false);
	if ((fd < 0) || (ptr == NULL)) {
		errno = ENFILE;
		return -1;
	}
	memset(ptr, 0, sizeof(struct fs_file_t));

	rc = fs_open(ptr, name);
	if (rc < 0) {
		posix_fs_free_fd(fd);
		errno = -rc;
		return -1;
	}

	return fd;
}

/**
 * @brief Close a file descriptor.
 *
 * See IEEE 1003.1
 */
int close(int fd)
{
	int rc;
	struct fs_file_t *ptr = NULL;

	if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) {
		errno = EBADF;
		return -1;
	}

	rc = fs_close(ptr);

	/* Free file ptr memory */
	posix_fs_free_fd(fd);

	if (rc < 0) {
		errno = -rc;
		return -1;
	}

	return 0;
}

/**
 * @brief Write to a file.
 *
 * See IEEE 1003.1
 */
ssize_t write(int fd, char *buffer, unsigned int count)
{
	ssize_t rc;
	struct fs_file_t *ptr = NULL;

	if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) {
		errno = EBADF;
		return -1;
	}

	rc = fs_write(ptr, buffer, count);
	if (rc < 0) {
		errno = -rc;
		return -1;
	}

	return rc;
}

/**
 * @brief Read from a file.
 *
 * See IEEE 1003.1
 */
ssize_t read(int fd, char *buffer, unsigned int count)
{
	ssize_t rc;
	struct fs_file_t *ptr = NULL;

	if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) {
		errno = EBADF;
		return -1;
	}

	rc = fs_read(ptr, buffer, count);
	if (rc < 0) {
		errno = -rc;
		return -1;
	}

	return rc;
}

/**
 * @brief Move read/write file offset.
 *
 * See IEEE 1003.1
 */
int lseek(int fd, int offset, int whence)
{
	int rc;
	struct fs_file_t *ptr = NULL;

	if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) {
		errno = EBADF;
		return -1;
	}

	rc = fs_seek(ptr, offset, whence);
	if (rc < 0) {
		errno = -rc;
		return -1;
	}

	return 0;
}

/**
 * @brief Open a directory stream.
 *
 * See IEEE 1003.1
 */
DIR *opendir(const char *dirname)
{
	int rc, fd;
	struct fs_dir_t *ptr = NULL;

	fd = posix_fs_alloc_fd((union file_desc **)&ptr, true);
	if ((fd < 0) || (ptr == NULL)) {
		errno = EMFILE;
		return NULL;
	}
	memset(ptr, 0, sizeof(struct fs_dir_t));

	rc = fs_opendir(ptr, dirname);
	if (rc < 0) {
		posix_fs_free_fd(fd);
		errno = -rc;
		return NULL;
	}

	return ptr;
}

/**
 * @brief Close a directory stream.
 *
 * See IEEE 1003.1
 */
int closedir(DIR *dirp)
{
	int rc;

	if (dirp == NULL) {
		errno = EBADF;
		return -1;
	}

	rc = fs_closedir(dirp);

	/* Free file ptr memory */
	posix_fs_free_ptr((struct posix_fs_desc *)dirp);

	if (rc < 0) {
		errno = -rc;
		return -1;
	}

	return 0;
}

/**
 * @brief Read a directory.
 *
 * See IEEE 1003.1
 */
struct dirent *readdir(DIR *dirp)
{
	int rc;

	if (dirp == NULL) {
		errno = EBADF;
		return NULL;
	}

	rc = fs_readdir(dirp, &fdirent);
	if (rc < 0) {
		errno = -rc;
		return NULL;
	}

	rc = strlen(fdirent.name);
	memcpy(pdirent.d_name, fdirent.name,
		rc <= PATH_MAX ? rc : PATH_MAX);
	return &pdirent;
}

/**
 * @brief Rename a file.
 *
 * See IEEE 1003.1
 */
int rename(const char *old, const char *new)
{
	int rc;

	rc = fs_rename(old, new);
	if (rc < 0) {
		errno = -rc;
		return -1;
	}

	return 0;
}

/**
 * @brief Remove a directory entry.
 *
 * See IEEE 1003.1
 */
int unlink(const char *path)
{
	int rc;

	rc = fs_unlink(path);
	if (rc < 0) {
		errno = -rc;
		return -1;
	}
	return 0;
}

/**
 * @brief Get file status.
 *
 * See IEEE 1003.1
 */
int stat(const char *path, struct stat *buf)
{
	int rc;
	struct fs_statvfs stat;

	if (buf == NULL) {
		errno = EBADF;
		return -1;
	}

	rc = fs_statvfs(path, &stat);
	if (rc < 0) {
		errno = -rc;
		return -1;
	}

	buf->st_size = stat.f_bsize * stat.f_blocks;
	buf->st_blksize = stat.f_bsize;
	buf->st_blocks = stat.f_blocks;
	return 0;
}

/**
 * @brief Make a directory.
 *
 * See IEEE 1003.1
 */
int mkdir(const char *path, mode_t mode)
{
	int rc;

	ARG_UNUSED(mode);

	rc = fs_mkdir(path);
	if (rc < 0) {
		errno = -rc;
		return -1;
	}

	return 0;
}
