#![no_std]
#![allow(nonstandard_style)]
#![allow(dead_code)]
#![allow(clippy::missing_safety_doc)]
#![allow(clippy::result_unit_err)]

use crate::sys::{calls::syscall2, constants::*, syscall3, syscall4, syscall5};

pub mod allocator;
pub mod env;
pub mod fd;
pub mod fs;
pub mod io;
pub mod mem;
pub mod net;
pub mod process;
pub mod sync;
pub mod sys;

extern crate alloc;

pub use sync::{FutexWaitResult, Mutex, MutexGuard, futex_wait, futex_wake};

/// # Safety
/// Caller must ensure the mount point path is a valid null-terminated string located in readable
/// memory and remains valid for the duration of the syscall.
pub unsafe fn sys_mount(
    device_id: u64,
    partition_idx: u64,
    path: *const u8,
    fs_type: *const u8,
) -> i64 {
    unsafe {
        syscall4(
            SYS_MOUNT,
            device_id,
            partition_idx,
            path as u64,
            fs_type as u64,
        ) as i64
    }
}

/// # Safety
/// Caller must ensure the buffer points to writable memory of at least `size` bytes and remains
/// valid for the duration of the syscall.
pub unsafe fn sys_list_partitions(buffer: *mut u8, size: usize) -> isize {
    unsafe { syscall2(SYS_LIST_PARTITIONS, buffer as u64, size as u64) as isize }
}

/// # Safety
/// Caller must ensure the buffer points to writable memory of at least `size` bytes and remains
/// valid for the duration of the syscall.
pub unsafe fn sys_list_mounts(buffer: *mut u8, size: usize) -> isize {
    unsafe { syscall2(SYS_LIST_MOUNTS, buffer as u64, size as u64) as isize }
}

/// # Safety
/// Caller must ensure:
/// - `buf` points to writable memory of at least `count` bytes
/// - Buffer remains valid for the duration of the syscall
/// - `flags` matches kernel expectations (currently must be zero)
pub unsafe fn sys_getrandom(buf: *mut u8, count: usize, flags: u64) -> isize {
    unsafe { syscall3(SYS_GETRANDOM, buf as u64, count as u64, flags) as isize }
}

/// # Safety
/// Caller must ensure `path` points to a valid null-terminated string that remains valid for the
/// duration of the syscall.
pub unsafe fn sys_spawn(
    path: *const u8,
    argv_ptr: *mut u8,
    stdin_fd: u64,
    stdout_fd: u64,
    stderr_fd: u64,
) -> u64 {
    unsafe {
        syscall5(
            SYS_SPAWN,
            path as u64,
            argv_ptr as u64,
            stdin_fd,
            stdout_fd,
            stderr_fd,
        )
    }
}
