# SPDX-License-Identifier: LSL-1.0
# Copyright (c) 2026 Markus Maiwald
# Stewardship: Self Sovereign Society Foundation
#
# This file is part of the Nexus Sovereign Core.

## Rumpk Layer 1: Typed Channels (SPEC-070)

import ion
import cspace

# Kernel logging
proc kprintln(s: cstring) {.importc, cdecl.}

proc get_channel_ring*(id: uint64): pointer =
  ## Map a Channel ID (object_id) to a physical HAL ring pointer
  case id:
  of 0x1000: return cast[pointer](chan_input.ring)
  of 0x1001: return cast[pointer](chan_tx.ring) # console.output
  of 0x500:  return cast[pointer](chan_net_tx.ring)
  of 0x501:  return cast[pointer](chan_net_rx.ring)
  else: return nil

proc channel_has_data*(id: uint64): bool =
  ## Check if a channel has data (for RX) or space (for TX)
  ## NOTE: This depends on whether the capability is for READ or WRITE.
  ## For now, we focus on RX (has data).
  let ring_ptr = get_channel_ring(id)
  if ring_ptr == nil: return false
  
  # Cast to a generic HAL_Ring to check head/tail
  # All IonPacket rings are 256 entries
  let ring = cast[ptr HAL_Ring[IonPacket]](ring_ptr)
  return ring.head != ring.tail

proc fiber_can_run_on_channels*(f_id: uint64, mask: uint64): bool {.exportc, cdecl.} =
  ## Check if any of the channels in the mask have active data
  if mask == 0: return true # Not waiting on anything specific
  
  for i in 0..<64:
    if (mask and (1'u64 shl i)) != 0:
      # Slot i is active in mask
      let cap = cspace_lookup(f_id, uint(i))
      if cap != nil:
        # Cast pointer to Capability struct (wait, we need the Nim definition)
        # Actually, let's just use a C helper if needed, but we can do it here.
        # Capability is 32 bytes. object_id is at offset 4 (wait, 1+1+2 = 4).
        let obj_id = cast[ptr uint64](cast[uint](cap) + 4)[]
        if channel_has_data(obj_id):
          return true
  return false
