// MARKUS MAIWALD (ARCHITECT) | VOXIS FORGE (AI)
// RUMPK HAL // SOVEREIGN CHANNELS (The Pipes)
// THE INVARIANT SHIELD - Phase 2 Task 1

const std = @import("std");

pub const IonPacket = extern struct {
    data: u64,
    phys: u64,
    len: u16,
    id: u16,
};

pub const CmdPacket = extern struct {
    kind: u32,
    _pad: u32, // Explicit Padding for 8-byte alignment
    arg: u64,
    id: u128, // SipHash Provenance (16 bytes)
};
// Size: 32 bytes (matches libs/membrane/ion.zig and core/ion.nim)

pub fn Ring(comptime T: type) type {
    return extern struct {
        head: u32,
        tail: u32,
        mask: u32,
        data: [256]T,
    };
}

// INVARIANT 1: The Handle Barrier
fn validate_ring_ptr(ptr: u64) void {
    // 0x8000_0000 is kernel base, 0x8300_0000 is ION base.
    if (ptr < 0x8000_0000) {
        @panic("HAL: Invariant Violation - Invalid Ring Pointer");
    }
}

fn pushGeneric(comptime T: type, ring: *Ring(T), pkt: T) bool {
    const head = @atomicLoad(u32, &ring.head, .monotonic);
    const tail = @atomicLoad(u32, &ring.tail, .monotonic);

    // INVARIANT 2: Overflow Protection
    const next = (head + 1) & ring.mask;
    if (next == tail) {
        return false;
    }

    ring.data[head & ring.mask] = pkt;
    @atomicStore(u32, &ring.head, next, .release);
    return true;
}

fn popGeneric(comptime T: type, ring: *Ring(T), out_pkt: *T) bool {
    const head = @atomicLoad(u32, &ring.head, .monotonic);
    const tail = @atomicLoad(u32, &ring.tail, .monotonic);

    // INVARIANT 3: Underflow Protection
    if (head == tail) {
        return false;
    }

    // Ensure we see data written by producer before reading it
    asm volatile ("fence r, rw" ::: .{ .memory = true });

    out_pkt.* = ring.data[tail & ring.mask];
    const next = (tail + 1) & ring.mask;
    @atomicStore(u32, &ring.tail, next, .release);
    return true;
}

// Exported ABI Functions (Hardened)
export fn hal_channel_push(handle: u64, pkt: IonPacket) bool {
    validate_ring_ptr(handle);
    const ring: *Ring(IonPacket) = @ptrFromInt(handle);
    return pushGeneric(IonPacket, ring, pkt);
}

export fn hal_channel_pop(handle: u64, out_pkt: *IonPacket) bool {
    validate_ring_ptr(handle);
    const ring: *Ring(IonPacket) = @ptrFromInt(handle);
    return popGeneric(IonPacket, ring, out_pkt);
}

export fn hal_cmd_push(handle: u64, pkt: CmdPacket) bool {
    validate_ring_ptr(handle);
    const ring: *Ring(CmdPacket) = @ptrFromInt(handle);
    return pushGeneric(CmdPacket, ring, pkt);
}

export fn hal_cmd_pop(handle: u64, out_pkt: *CmdPacket) bool {
    validate_ring_ptr(handle);
    const ring: *Ring(CmdPacket) = @ptrFromInt(handle);
    return popGeneric(CmdPacket, ring, out_pkt);
}
