// std.time — wall and monotonic clocks over clock_gettime(2)
// (PLAN-HTTPZ S1).
//
//   now_secs()  wall clock, unix epoch seconds (CLOCK_REALTIME).
//   mono_ms()   monotonic milliseconds for deadlines/timeouts —
//               unaffected by wall-clock steps (NTP, manual set);
//               meaningful only as a difference between two reads in
//               one process, never as an absolute time.
//
// PER-OS: clock ids differ (CLOCK_MONOTONIC is 6 on darwin, 1 on
// linux); the constants below are darwin's. Per-OS selection is
// PLAN-HTTPZ C3 — until it lands this module is correct on the gate's
// host (darwin) only.
//
// No error channel: clock_gettime fails only on an unknown clock id
// (ours are module constants) or a bad pointer (ours is a stack slot),
// so the wrappers are total.

libc :: #library "c";

// darwin struct timespec: tv_sec and tv_nsec are both C long (i64).
Timespec :: struct {
    sec: i64;
    nsec: i64;
}

clock_gettime :: (clock_id: i32, ts: *Timespec) -> i32 extern libc;

CLOCK_REALTIME  :i32: 0;
CLOCK_MONOTONIC :i32: 6;   // darwin; linux is 1 (C3 selects per-OS)

// Wall clock as unix epoch seconds.
now_secs :: () -> i64 {
    ts : Timespec = .{};
    clock_gettime(CLOCK_REALTIME, @ts);
    return ts.sec;
}

// Monotonic milliseconds since an arbitrary process-local origin.
mono_ms :: () -> i64 {
    ts : Timespec = .{};
    clock_gettime(CLOCK_MONOTONIC, @ts);
    return ts.sec * 1000 + ts.nsec / 1000000;
}
