//! Mapped-pinned slot round-trip tests.

use ml_alpha::pinned::{FillPayload, MappedPinnedFillSlot, MappedPinnedSnapshotSlot, SnapshotPayload};
use ml_core::device::MlDevice;

fn test_device() -> MlDevice {
    MlDevice::cuda(0).expect("CUDA 0 required for ml-alpha tests")
}

#[test]
fn snapshot_slot_round_trip() {
    let _dev = test_device();
    let mut slot = MappedPinnedSnapshotSlot::new().expect("alloc");
    let mut payload = SnapshotPayload {
        ts_ns: 1_700_000_000_000_000_000,
        valid: 1,
        ..Default::default()
    };
    payload.features[0] = 1.25;
    payload.features[1] = -0.5;
    payload.features[31] = 99.0;
    slot.write_volatile(&payload);
    let observed = slot.peek();
    assert_eq!(observed.ts_ns, payload.ts_ns);
    assert_eq!(observed.valid, 1);
    assert_eq!(observed.features[0], 1.25);
    assert_eq!(observed.features[1], -0.5);
    assert_eq!(observed.features[31], 99.0);
    assert!(slot.device_ptr() != 0, "snapshot slot must have nonzero device pointer");
}

#[test]
fn fill_slot_round_trip() {
    let _dev = test_device();
    let mut slot = MappedPinnedFillSlot::new().expect("alloc");
    let payload = FillPayload {
        fill_price: 5500.25,
        fill_qty: 1.0,
        side: 1.0,
        commission: 0.85,
        ts_ns: 1_700_000_001_000_000_000,
        _pad: [0.0; 3],
    };
    slot.write_volatile(&payload);
    let observed = slot.peek();
    assert_eq!(observed.fill_price, 5500.25);
    assert_eq!(observed.fill_qty, 1.0);
    assert_eq!(observed.side, 1.0);
    assert_eq!(observed.commission, 0.85);
    assert_eq!(observed.ts_ns, payload.ts_ns);
    assert!(slot.device_ptr() != 0);
}

#[test]
fn snapshot_slot_reuses_pinned_pages() {
    let _dev = test_device();
    let mut slot = MappedPinnedSnapshotSlot::new().expect("alloc");
    let dev_ptr_1 = slot.device_ptr();
    let mut p = SnapshotPayload::default();
    p.features[0] = 1.0;
    slot.write_volatile(&p);
    let dev_ptr_2 = slot.device_ptr();
    assert_eq!(dev_ptr_1, dev_ptr_2, "device ptr must be stable across writes (pre-allocation invariant)");
}
