# 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.
# See legal/LICENSE_SOVEREIGN.md for license terms.

## Rumpk Layer 1: Sovereign VFS (The Loom)
##
## Freestanding implementation (No OS module dependencies).
## Uses fixed-size arrays for descriptors to ensure deterministic latency.

import tar, sfs

type
  VFSMode = enum
    MODE_TAR, MODE_SFS, MODE_RAM, MODE_TTY

  MountPoint = object
    prefix: array[32, char]
    mode: VFSMode

  FileHandle = object
    path: array[64, char]
    offset: uint64
    mode: VFSMode
    active: bool

const MAX_MOUNTS = 8
const MAX_FDS = 32

var mnt_table: array[MAX_MOUNTS, MountPoint]
var mnt_count: int = 0

var fd_table: array[MAX_FDS, FileHandle]

# Helper: manual string compare
proc vfs_starts_with(s, prefix: cstring): bool =
  let ps = cast[ptr UncheckedArray[char]](s)
  let pp = cast[ptr UncheckedArray[char]](prefix)
  var i = 0
  while pp[i] != '\0':
    if ps[i] != pp[i]: return false
    i += 1
  return true

proc vfs_streq(s1, s2: cstring): bool =
  let p1 = cast[ptr UncheckedArray[char]](s1)
  let p2 = cast[ptr UncheckedArray[char]](s2)
  var i = 0
  while true:
    if p1[i] != p2[i]: return false
    if p1[i] == '\0': return true
    i += 1

proc vfs_add_mount(prefix: cstring, mode: VFSMode) =
  if mnt_count >= MAX_MOUNTS: return
  let p = cast[ptr UncheckedArray[char]](prefix)
  var i = 0
  while p[i] != '\0' and i < 31:
    mnt_table[mnt_count].prefix[i] = p[i]
    i += 1
  mnt_table[mnt_count].prefix[i] = '\0'
  mnt_table[mnt_count].mode = mode
  mnt_count += 1

proc vfs_mount_init*() =
  # Restore the SPEC-502 baseline
  vfs_add_mount("/nexus", MODE_SFS)
  vfs_add_mount("/sysro", MODE_TAR)
  vfs_add_mount("/state", MODE_RAM)
  vfs_add_mount("/dev/tty", MODE_TTY)
  vfs_add_mount("/Bus/Console/tty0", MODE_TTY)

proc resolve_path(path: cstring): (VFSMode, int) =
  for i in 0..<mnt_count:
    let prefix = cast[cstring](addr mnt_table[i].prefix[0])
    if vfs_starts_with(path, prefix):
      var len = 0
      while mnt_table[i].prefix[len] != '\0': len += 1
      return (mnt_table[i].mode, len)
  return (MODE_TAR, 0)

proc ion_vfs_open*(path: cstring, flags: int32): int32 {.exportc, cdecl.} =
  let (mode, prefix_len) = resolve_path(path)
  
  # Delegate internal open
  let sub_path = cast[cstring](cast[uint64](path) + uint64(prefix_len))
  var internal_fd: int32 = -1
  
  case mode:
  of MODE_TAR, MODE_RAM: internal_fd = tar.vfs_open(sub_path, flags)
  of MODE_SFS: internal_fd = 0 # Shim
  of MODE_TTY: internal_fd = 1 # Shim
  
  if internal_fd >= 0:
    for i in 0..<MAX_FDS:
      if not fd_table[i].active:
        fd_table[i].active = true
        fd_table[i].mode = mode
        fd_table[i].offset = 0
        let p = cast[ptr UncheckedArray[char]](sub_path)
        var j = 0
        while p[j] != '\0' and j < 63:
           fd_table[i].path[j] = p[j]
           j += 1
        fd_table[i].path[j] = '\0'
        return int32(i + 3) # FDs start at 3
  return -1

proc ion_vfs_read*(fd: int32, buf: pointer, count: uint64): int64 {.exportc, cdecl.} =
  let idx = int(fd - 3)
  if idx < 0 or idx >= MAX_FDS or not fd_table[idx].active: return -1
  let fh = addr fd_table[idx]
  
  case fh.mode:
  of MODE_TTY: return -2
  of MODE_TAR, MODE_RAM:
     let path = cast[cstring](addr fh.path[0])
     let n = tar.vfs_read_at(path, buf, count, fh.offset)
     if n > 0: fh.offset += uint64(n)
     return n
  of MODE_SFS:
     let path = cast[cstring](addr fh.path[0])
     var temp: array[256, byte] # Small shim
     let n = sfs.sfs_read_file(path, addr temp[0], 256)
     if n <= 0: return -1
     let avail = uint64(n) - fh.offset
     let actual = if count < avail: count else: avail
     if actual > 0:
        copyMem(buf, addr temp[int(fh.offset)], int(actual))
        fh.offset += actual
        return int64(actual)
     return 0

proc ion_vfs_write*(fd: int32, buf: pointer, count: uint64): int64 {.exportc, cdecl.} =
  let idx = int(fd - 3)
  if idx < 0 or idx >= MAX_FDS or not fd_table[idx].active: return -1
  let fh = addr fd_table[idx]
  
  case fh.mode:
  of MODE_TTY: return -2
  of MODE_TAR, MODE_RAM:
     let path = cast[cstring](addr fh.path[0])
     let n = tar.vfs_write_at(path, buf, count, fh.offset)
     if n > 0: fh.offset += uint64(n)
     return n
  of MODE_SFS:
     let path = cast[cstring](addr fh.path[0])
     sfs.sfs_write_file(path, buf, int(count))
     return int64(count)

proc ion_vfs_close*(fd: int32): int32 {.exportc, cdecl.} =
  let idx = int(fd - 3)
  if idx >= 0 and idx < MAX_FDS:
    fd_table[idx].active = false
    return 0
  return -1

proc ion_vfs_list*(buf: pointer, max_len: uint64): int64 {.exportc, cdecl.} =
  # Hardcoded baseline for now to avoid string/os dependency
  let msg = "/nexus\n/sysro\n/state\n"
  let n = if uint64(msg.len) < max_len: uint64(msg.len) else: max_len
  if n > 0: copyMem(buf, unsafeAddr msg[0], int(n))
  return int64(n)
