//! This would've been called `io`, but rust-analyzer refuses to see
//! the submodules of this module when it's named `io`.

use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::null_mut};

use log::info;

pub mod file;
pub mod dir;

pub use file::*;
pub use dir::*;

// File management

#[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_fopen(
    filename: *const c_char,
    mode: *const c_char,
) -> *mut FILE {
    todo!()
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_fclose(file: *mut FILE) -> c_int {
    todo!()
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_fseek(
    stream: *mut FILE,
    offset: c_long,
    whence: c_int,
) -> c_int {
    todo!()
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_ftell(stream: *mut FILE) -> c_long {
    todo!()
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_fread(
    ptr: *mut c_void,
    size: c_size_t,
    nobj: c_size_t,
    stream: *mut FILE,
) -> c_size_t {
    todo!()
}

// Printing

#[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_fprintf(
    stream: *mut FILE,
    format: *const c_char,
    mut args: ...
) -> c_int {
    unsafe { __xkbc_vfprintf(stream, format, args.as_va_list()) }
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_vfprintf(stream: *mut FILE, format: *const c_char, ap: VaList) -> c_int {
    if stream == STDOUT || stream == STDERR {
        let string = ::alloc::format!("vfprintf({:?}, {:?}, {:?})", stream, format, ap);
        info!("{}", string);
        string.len() as c_int
    } else {
        -1
    }
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_vasprintf(strp: *mut *mut c_char, fmt: *const c_char, ap: VaList) -> c_int {
    todo!()
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_vsnprintf(string: *mut c_char, size: c_size_t, format: *const c_char, ap: VaList) -> c_int {
    todo!()
}

#[unsafe(no_mangle)]
pub unsafe extern "C" fn __xkbc_snprintf(
    s: *mut c_char,
    n: c_size_t,
    format: *const c_char,
    ...
) -> c_int {
    todo!()
}
