use core::{
    ffi::{c_char, c_int},
    ptr::NonNull,
    slice,
};

use crate::{
    allocator::c_alloc,
    error::{self, CPtrResult, CResult},
    headers::errno::Errno,
    io,
    util::PointerStrExt,
};

#[no_mangle]
unsafe extern "C" fn grantpt(_fd: c_int) -> c_int {
    todo!()
}

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

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

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

#[no_mangle]
unsafe extern "C" fn posix_openpt(_fd: c_int) -> c_int {
    todo!()
}

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

#[no_mangle]
unsafe extern "C" fn realpath(
    path: *const c_char,
    resolved_ptr: *mut c_char,
) -> CPtrResult<c_char> {
    if path.is_null() {
        error::set_errno(Errno::EINVAL);
        return CPtrResult::ERROR;
    }
    let path = path.ensure_str();
    let resolved = io::realpath(path)?;

    let ptr = if let Some(ptr) = NonNull::new(resolved_ptr) {
        ptr
    } else {
        c_alloc(4096, 1, false)?.cast()
    };

    let buffer = slice::from_raw_parts_mut(resolved_ptr.cast::<u8>(), 4096);
    let src = resolved.as_str();

    assert!(src.len() < 4096);
    buffer[..src.len()].copy_from_slice(src.as_bytes());
    buffer[src.len()] = 0;

    CPtrResult::success(ptr)
}

#[no_mangle]
unsafe extern "C" fn unlockpt(_fd: c_int) -> c_int {
    todo!()
}
