# Standard C Types
# cint, csize_t are in system/ctypes (implicitly available?)
# If not, we fix it by aliasing system ones or just using int/uint.
# Let's try relying on system.
type
  cptr* = pointer

# Standard POSIX-ish Wrappers (from libc_shim)
proc write*(fd: cint, buf: cptr, count: csize_t): csize_t {.importc, cdecl.}
proc read*(fd: cint, buf: cptr, count: csize_t): csize_t {.importc, cdecl.}
proc open*(pathname: cstring, flags: cint): cint {.importc, cdecl.}
proc close*(fd: cint): cint {.importc, cdecl.}
proc exit*(status: cint) {.importc, cdecl.}
proc list_files*(buf: pointer, len: uint64): int64 {.importc, cdecl.}

# Our Custom Syscalls (Defined in libc_shim)
proc nexus_syscall*(cmd: cint, arg: uint64): cint {.importc, cdecl.}
proc nexus_yield*() {.importc, cdecl.}
proc nexus_net_tx*(buf: cptr, len: uint64) {.importc, cdecl.}
proc nexus_net_rx*(buf: cptr, max_len: uint64): uint64 {.importc, cdecl.}
proc nexus_blk_read*(sector: uint64, buf: cptr, len: uint64) {.importc, cdecl.}
proc nexus_blk_write*(sector: uint64, buf: cptr, len: uint64) {.importc, cdecl.}

type
  FileArgs* = object
    name*: uint64
    data*: uint64
    len*: uint64

const CMD_FS_WRITE = 0x203

proc nexus_file_write*(name: string, data: string) =
  var args: FileArgs
  args.name = cast[uint64](cstring(name))
  args.data = cast[uint64](cstring(data))
  args.len = uint64(data.len)
  discard nexus_syscall(cint(CMD_FS_WRITE), cast[uint64](addr args))

# Helper: Print to Stdout (FD 1)
proc print*(s: string) =
  if s.len > 0:
    discard write(1, unsafeAddr s[0], csize_t(s.len))
  var nl = "\n"
  discard write(1, unsafeAddr nl[0], 1)

proc print_raw*(s: string) =
  if s.len > 0:
    discard write(1, unsafeAddr s[0], csize_t(s.len))

proc print_int*(n: int) =
  var s = ""
  var v = n
  if v == 0: s = "0"
  else:
    while v > 0:
      s.add(char((v mod 10) + 48))
      v = v div 10
  # Reverse
  var r = ""
  var i = s.len - 1
  while i >= 0:
    r.add(s[i])
    i -= 1
  print_raw(r)

var read_buffer: array[512, char]
var read_pos = 0
var read_len = 0

# Need to pull poll_network from somewhere?
# Or just define a dummy or export proper one?
# poll_network logic causes circular dep if it's in main.
# Let's make my_readline simpler for now, or move poll_network here?
# poll_network uses `nexus_net_rx`.
# Let's move poll_network to std?
# It depends on `nipbox` logic (checksums?).
# Let's just do blocking read in my_readline for now without network polling for Phase 12 MVP.
# Actually `libc_shim` `read(0)` is synchronous (busy wait on ring).
# So poll_network inside loop was useful.
# We will skip net poll in readline for this refactor to avoid complexity.

proc my_readline*(out_str: var string): bool =
  out_str = ""
  while true:
    var c: char
    let n = read(0, addr c, 1)
    if n <= 0: return false # EOF or Error

    if c == '\n' or c == '\r':
      print_raw("\n")
      return true
    elif c == '\b' or c == char(127): # Backspace
      if out_str.len > 0:
        # Visual backspace
        var bs = "\b \b"
        discard write(1, addr bs[0], 3)
        out_str.setLen(out_str.len - 1)
    else:
      out_str.add(c)
      discard write(1, addr c, 1) # Echo

