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

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

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

/* list of mounted file systems */
static sys_dlist_t disk_access_list = SYS_DLIST_STATIC_INIT(&disk_access_list);

/* lock to protect storage layer registration */
static struct k_spinlock lock;

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_spinlock_key_t spinlock_key = k_spin_lock(&lock);

	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_spin_unlock(&lock, spinlock_key);

	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->refcnt == 0U)) {
		/* Disk has not been initialized, start it */
		if ((disk->ops != NULL) && (disk->ops->init != NULL)) {
			rc = disk->ops->init(disk);
			if (rc == 0) {
				/* Increment reference count */
				disk->refcnt++;
			}
		}
	} else if ((disk != NULL) && (disk->refcnt < UINT16_MAX)) {
		/* Disk reference count is nonzero, simply increment it */
		disk->refcnt++;
		rc = 0;
	}

	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, uint8_t *data_buf,
		     uint32_t start_sector, uint32_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 uint8_t *data_buf,
		      uint32_t start_sector, uint32_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, uint8_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)) {
		switch (cmd) {
		case DISK_IOCTL_CTRL_INIT:
			if (disk->refcnt == 0U) {
				rc = disk->ops->ioctl(disk, cmd, buf);
				if (rc == 0) {
					disk->refcnt++;
				}
			} else if (disk->refcnt < UINT16_MAX) {
				disk->refcnt++;
				rc = 0;
			} else {
				LOG_ERR("Disk reference count at max value");
			}
			break;
		case DISK_IOCTL_CTRL_DEINIT:
			if ((buf != NULL) && (*((bool *)buf))) {
				/* Force deinit disk */
				disk->refcnt = 0U;
				disk->ops->ioctl(disk, cmd, buf);
				rc = 0;
			} else if (disk->refcnt == 1U) {
				rc = disk->ops->ioctl(disk, cmd, buf);
				if (rc == 0) {
					disk->refcnt--;
				}
			} else if (disk->refcnt > 0) {
				disk->refcnt--;
				rc = 0;
			} else {
				LOG_WRN("Disk is already deinitialized");
			}
			break;
		default:
			rc = disk->ops->ioctl(disk, cmd, buf);
		}
	}

	return rc;
}

int disk_access_register(struct disk_info *disk)
{
	k_spinlock_key_t spinlock_key;

	if ((disk == NULL) || (disk->name == NULL)) {
		LOG_ERR("invalid disk interface!!");
		return -EINVAL;
	}

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

	/* Initialize reference count to zero */
	disk->refcnt = 0U;

	spinlock_key = k_spin_lock(&lock);
	/*  append to the disk list */
	sys_dlist_append(&disk_access_list, &disk->node);
	LOG_DBG("disk interface(%s) registered", disk->name);
	k_spin_unlock(&lock, spinlock_key);
	return 0;
}

int disk_access_unregister(struct disk_info *disk)
{
	k_spinlock_key_t spinlock_key;

	if ((disk == NULL) || (disk->name == NULL)) {
		LOG_ERR("invalid disk interface!!");
		return -EINVAL;
	}

	if (disk_access_get_di(disk->name) == NULL) {
		LOG_ERR("disk interface not registered!!");
		return -EINVAL;
	}

	spinlock_key = k_spin_lock(&lock);
	/* remove disk node from the list */
	sys_dlist_remove(&disk->node);
	k_spin_unlock(&lock, spinlock_key);
	LOG_DBG("disk interface(%s) unregistered", disk->name);
	return 0;
}
