//! Probe surfaces — Linux-only.
//!
//! Each submodule wraps one [`probe_source`](crate::probe_source) family.
//! Probes emit [`ProbeEvent`](crate::ProbeEvent)s into a bounded MPSC-style
//! queue; the binary entrypoint drains the queue and writes CBOR frames to
//! the host vsock with drop-with-counter back-pressure (ADR-0006 §5.3).
//!
//! All probe code is Linux-gated. On other targets the crate compiles to a
//! shell so the workspace stays buildable on Windows / macOS dev machines.

#[cfg(target_os = "linux")]
pub mod process;

#[cfg(target_os = "linux")]
pub mod capability;

#[cfg(target_os = "linux")]
pub mod inotify;

#[cfg(target_os = "linux")]
pub mod net_connect;

/// Shared monotonic timestamp helper used by every probe so a single
/// agent emits a strictly-increasing sequence of `guest_monotonic_ns`
/// values regardless of which probe fired.
#[cfg(target_os = "linux")]
#[allow(unsafe_code)]
pub fn now_monotonic_ns() -> u64 {
    // SAFETY: clock_gettime with CLOCK_MONOTONIC and a stack-allocated
    // timespec is always sound; the kernel writes 16 bytes on success.
    let mut ts = libc::timespec {
        tv_sec: 0,
        tv_nsec: 0,
    };
    let ret = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut ts) };
    if ret != 0 {
        // The CLOCK_MONOTONIC clock_id is mandatory on Linux; a failure
        // here means the agent's environment is too broken to trust, so
        // we fall back to 0 and let the host's `host_received_at` stamp
        // carry the ordering.
        return 0;
    }
    (ts.tv_sec as u64).saturating_mul(1_000_000_000) + (ts.tv_nsec as u64)
}

/// Non-Linux fallback so consumers can still call the function from
/// portable code; returns 0.
#[cfg(not(target_os = "linux"))]
pub fn now_monotonic_ns() -> u64 {
    0
}
