use super::{MemoryError, MemorySample};
use std::time::Instant;

pub fn sample_memory(pid: u32) -> Result<MemorySample, MemoryError> {
    use std::mem;
    use std::ptr;

    let mut mib = [
        libc::CTL_KERN,
        libc::KERN_PROC,
        libc::KERN_PROC_PID,
        pid as libc::c_int,
    ];

    let mut kinfo: libc::kinfo_proc = unsafe { mem::zeroed() };
    let mut size = mem::size_of::<libc::kinfo_proc>();

    let ret = unsafe {
        libc::sysctl(
            mib.as_mut_ptr(),
            mib.len() as u32,
            &mut kinfo as *mut _ as *mut libc::c_void,
            &mut size,
            ptr::null_mut(),
            0,
        )
    };

    if ret != 0 {
        return match unsafe { *libc::__errno_location() } {
            libc::ESRCH => Err(MemoryError::ProcessNotFound(pid)),
            _ => Err(MemoryError::Io(std::io::Error::last_os_error())),
        };
    }

    // Get page size for conversion
    let page_size = unsafe { libc::sysconf(libc::_SC_PAGESIZE) } as u64;

    Ok(MemorySample {
        timestamp: Instant::now(),
        rss_bytes: kinfo.ki_rssize as u64 * page_size,
        peak_rss_bytes: kinfo.ki_rssize as u64 * page_size, // FreeBSD doesn't track peak
        virtual_bytes: kinfo.ki_size,
        swap_bytes: 0, // Not directly available
    })
}
