use std::{io, os::fd::RawFd, path::Path};

use runtime::rt as yggdrasil_rt;
use yggdrasil_rt::io::{FileMetadataUpdate, FileMetadataUpdateMode, FileMode as RawFileMode};

use crate::fs::FileModeUpdate;

pub fn update_file_mode<P: AsRef<Path>>(
    at: Option<RawFd>,
    path: P,
    mode: FileModeUpdate,
) -> io::Result<()> {
    // TODO make a soft error?
    let path_str = path.as_ref().to_str().expect("Path is not a valid string");
    let raw_update_mode = match mode {
        FileModeUpdate::Set(mode) => {
            let raw_file_mode = unsafe { RawFileMode::from_raw(mode.bits()) };
            FileMetadataUpdateMode::Set(raw_file_mode)
        }
        FileModeUpdate::Modify { set, clear } => {
            let raw_set_mode = unsafe { RawFileMode::from_raw(set.bits()) };
            let raw_clear_mode = unsafe { RawFileMode::from_raw(clear.bits()) };
            FileMetadataUpdateMode::Modify {
                set: raw_set_mode,
                clear: raw_clear_mode,
            }
        }
    };
    unsafe {
        yggdrasil_rt::sys::update_metadata(
            at,
            path_str,
            &FileMetadataUpdate::Permissions(raw_update_mode),
        )
        .map_err(io::Error::from)
    }
}
