use core::ffi::{c_char, c_int};

use yggdrasil_rt::{
    io::{RemoveFlags, Rename},
    sys as syscall,
};

use crate::{
    error::{self, CIntZeroResult, CPtrResult, ResultExt},
    headers::{errno::Errno, fcntl::AT_FDCWD},
    io::managed::{stderr, FILE},
    util::{self, PointerExt, PointerStrExt},
};

#[no_mangle]
unsafe extern "C" fn perror(message: *const c_char) {
    let out = stderr.ensure_mut();
    out.lock();

    if !message.is_null() {
        let message = message.ensure_cstr();
        out.write_unlocked(message.to_bytes()).ok();
        out.write_unlocked(b": ").ok();
    }

    #[allow(static_mut_refs)]
    out.write_unlocked(error::get_errno().to_c_str().to_bytes())
        .ok();
    out.write_unlocked(b"\n").ok();

    out.unlock();
}

#[no_mangle]
unsafe extern "C" fn ctermid(_buf: *mut c_char) -> *mut c_char {
    unimplemented!()
}

#[no_mangle]
unsafe extern "C" fn remove(path: *const c_char) -> CIntZeroResult {
    let path = path.ensure_str();
    syscall::remove(None, path, RemoveFlags::DIRECTORY).e_map_err(Errno::from)?;
    CIntZeroResult::SUCCESS
}

#[no_mangle]
unsafe extern "C" fn rename(src: *const c_char, dst: *const c_char) -> CIntZeroResult {
    renameat(AT_FDCWD, src, AT_FDCWD, dst)
}

#[no_mangle]
unsafe extern "C" fn renameat(
    old_atfd: c_int,
    src: *const c_char,
    new_atfd: c_int,
    dst: *const c_char,
) -> CIntZeroResult {
    let old_at = util::at_fd(old_atfd)?;
    let new_at = util::at_fd(new_atfd)?;
    let source = src.ensure_str();
    let destination = dst.ensure_str();

    syscall::rename(&Rename {
        source_at: old_at,
        destination_at: new_at,
        source,
        destination,
    })
    .e_map_err(Errno::from)?;

    CIntZeroResult::SUCCESS
}

#[no_mangle]
unsafe extern "C" fn tempnam(_dir: *const c_char, _prefix: *const c_char) -> *mut c_char {
    todo!()
}

#[no_mangle]
unsafe extern "C" fn tmpfile() -> CPtrResult<FILE> {
    todo!()
}

#[no_mangle]
unsafe extern "C" fn tmpnam(_template: *mut c_char) -> *mut c_char {
    todo!()
}
