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

#include <string.h>
#include <zephyr/types.h>
#include <misc/__assert.h>
#include <misc/util.h>
#include <init.h>
#include <disk_access.h>
#include <errno.h>
#include <device.h>

#define LOG_LEVEL CONFIG_DISK_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(disk);

/* list of mounted file systems */
static sys_dlist_t disk_access_list;

/* lock to protect storage layer registration */
static struct k_mutex mutex;

struct disk_info *disk_access_get_di(const char *name)
{
	struct disk_info *disk = NULL, *itr;
	size_t name_len = strlen(name);
	sys_dnode_t *node;

	k_mutex_lock(&mutex, K_FOREVER);
	SYS_DLIST_FOR_EACH_NODE(&disk_access_list, node) {
		itr = CONTAINER_OF(node, struct disk_info, node);

		/*
		 * Move to next node if mount point length is
		 * shorter than longest_match match or if path
		 * name is shorter than the mount point name.
		 */
		if (strlen(itr->name) != name_len) {
			continue;
		}

		/* Check for disk name match */
		if (strncmp(name, itr->name, name_len) == 0) {
			disk = itr;
			break;
		}
	}
	k_mutex_unlock(&mutex);

	return disk;
}

int disk_access_init(const char *pdrv)
{
	struct disk_info *disk = disk_access_get_di(pdrv);
	int rc = -EINVAL;

	if ((disk != NULL) && (disk->ops != NULL) &&
				(disk->ops->init != NULL)) {
		rc = disk->ops->init(disk);
	}

	return rc;
}

int disk_access_status(const char *pdrv)
{
	struct disk_info *disk = disk_access_get_di(pdrv);
	int rc = -EINVAL;

	if ((disk != NULL) && (disk->ops != NULL) &&
				(disk->ops->status != NULL)) {
		rc = disk->ops->status(disk);
	}

	return rc;
}

int disk_access_read(const char *pdrv, u8_t *data_buf,
		     u32_t start_sector, u32_t num_sector)
{
	struct disk_info *disk = disk_access_get_di(pdrv);
	int rc = -EINVAL;

	if ((disk != NULL) && (disk->ops != NULL) &&
				(disk->ops->read != NULL)) {
		rc = disk->ops->read(disk, data_buf, start_sector, num_sector);
	}

	return rc;
}

int disk_access_write(const char *pdrv, const u8_t *data_buf,
		      u32_t start_sector, u32_t num_sector)
{
	struct disk_info *disk = disk_access_get_di(pdrv);
	int rc = -EINVAL;

	if ((disk != NULL) && (disk->ops != NULL) &&
				(disk->ops->write != NULL)) {
		rc = disk->ops->write(disk, data_buf, start_sector, num_sector);
	}

	return rc;
}

int disk_access_ioctl(const char *pdrv, u8_t cmd, void *buf)
{
	struct disk_info *disk = disk_access_get_di(pdrv);
	int rc = -EINVAL;

	if ((disk != NULL) && (disk->ops != NULL) &&
				(disk->ops->ioctl != NULL)) {
		rc = disk->ops->ioctl(disk, cmd, buf);
	}

	return rc;
}

int disk_access_register(struct disk_info *disk)
{
	int rc = 0;

	k_mutex_lock(&mutex, K_FOREVER);
	if ((disk == NULL) || (disk->name == NULL)) {
		LOG_ERR("invalid disk interface!!");
		rc = -EINVAL;
		goto reg_err;
	}

	if (disk_access_get_di(disk->name) != NULL) {
		LOG_ERR("disk interface already registered!!");
		rc = -EINVAL;
		goto reg_err;
	}

	/*  append to the disk list */
	sys_dlist_append(&disk_access_list, &disk->node);
	LOG_DBG("disk interface(%s) registred", disk->name);
reg_err:
	k_mutex_unlock(&mutex);
	return rc;
}

int disk_access_unregister(struct disk_info *disk)
{
	int rc = 0;

	k_mutex_lock(&mutex, K_FOREVER);
	if ((disk == NULL) || (disk->name == NULL)) {
		LOG_ERR("invalid disk interface!!");
		rc = -EINVAL;
		goto unreg_err;
	}

	if (disk_access_get_di(disk->name) == NULL) {
		LOG_ERR("disk interface not registered!!");
		rc = -EINVAL;
		goto unreg_err;
	}
	/* remove disk node from the list */
	sys_dlist_remove(&disk->node);
	LOG_DBG("disk interface(%s) unregistred", disk->name);
unreg_err:
	k_mutex_unlock(&mutex);
	return rc;
}

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

	k_mutex_init(&mutex);
	sys_dlist_init(&disk_access_list);
	return 0;
}

SYS_INIT(disk_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
