use alloc::{boxed::Box, vec::Vec};
use async_trait::async_trait;
use libk_util::sync::spin_rwlock::IrqSafeRwLock;
use yggdrasil_abi::error::Error;

use super::NodeRef;

#[async_trait]
pub trait Filesystem: Sync + Send {
    async fn flush(&self) -> Result<(), Error> {
        Ok(())
    }

    fn display_name(&self) -> &'static str;
}

static FILESYSTEM_ROOTS: IrqSafeRwLock<Vec<NodeRef>> = IrqSafeRwLock::new(Vec::new());

pub enum FilesystemMountOption<'a> {
    // Common options
    Sync,
    // Filesystem-specific options
    FsSpecific(&'a str),
}

pub fn parse_mount_options(
    options: Option<&str>,
) -> impl Iterator<Item = FilesystemMountOption<'_>> {
    options
        .unwrap_or("")
        .trim()
        .split(" ")
        .map(|word| match word {
            "sync" => FilesystemMountOption::Sync,
            _ => FilesystemMountOption::FsSpecific(word),
        })
}

pub fn register_root(root: NodeRef) {
    if let Some(fs) = root.filesystem() {
        log::info!("Register filesystem root: {}", fs.display_name());
        FILESYSTEM_ROOTS.write().push(root);
    }
}

pub fn roots() -> &'static IrqSafeRwLock<Vec<NodeRef>> {
    &FILESYSTEM_ROOTS
}
