// ValueManagerBox - Unified register value management
// Centralizes all register get/set operations with type conversion

using selfhost.shared.common.string_helpers as StringHelpers
using selfhost.vm.boxes.result_box as Result

static box ValueManagerBox {
  // Get register value (returns 0 if not found)
  // reg_id: numeric register ID (e.g., 1, 2, 3)
  // Returns: register value or 0 if not set
  get(regs, reg_id) {
    local key = StringHelpers.int_to_str(reg_id)
    local v = regs.get(key)
    return v
  }

  // Set register value
  // reg_id: numeric register ID
  // value: value to store
  // Returns: Result.Ok(0)
  set(regs, reg_id, value) {
    local key = StringHelpers.int_to_str(reg_id)
    regs.set(key, value)
    return Result.Ok(0)
  }

  // Get register as i64 (with type conversion if needed)
  // Currently same as get(), but allows future type handling
  get_i64(regs, reg_id) {
    return me.get(regs, reg_id)
  }

  // Set register with automatic type conversion
  // Currently same as set(), but allows future type handling
  set_i64(regs, reg_id, value) {
    return me.set(regs, reg_id, value)
  }

  // --- Metadata helpers for core-compatible collection ops ---
  _meta_key() { return "__core_meta" }
  _meta(regs) {
    local key = me._meta_key()
    local meta = regs.get(key)
    if meta == null {
      meta = new MapBox()
      regs.set(key, meta)
    }
    return meta
  }
  _arr_key(reg_id) { return "arrsize:r" + StringHelpers.int_to_str(reg_id) }
  _map_len_key(reg_id) { return "maplen:r" + StringHelpers.int_to_str(reg_id) }
  _map_entry_key(reg_id, key_str) { return "mapentry:r" + StringHelpers.int_to_str(reg_id) + ":" + key_str }

  set_array_size(regs, reg_id, size) {
    me._meta(regs).set(me._arr_key(reg_id), size)
    return Result.Ok(0)
  }
  get_array_size(regs, reg_id) {
    local v = me._meta(regs).get(me._arr_key(reg_id))
    if v == null { return 0 }
    return v
  }
  has_array_meta(regs, reg_id) {
    return me._meta(regs).get(me._arr_key(reg_id)) != null
  }
  inc_array_size(regs, reg_id, delta) {
    local cur = me.get_array_size(regs, reg_id)
    local next = cur + delta
    if next < 0 { next = 0 }
    me.set_array_size(regs, reg_id, next)
    return next
  }

  ensure_map_meta(regs, reg_id) {
    local meta = me._meta(regs)
    local key = me._map_len_key(reg_id)
    if meta.get(key) == null { meta.set(key, 0) }
    return meta.get(key)
  }
  get_map_len(regs, reg_id) {
    me.ensure_map_meta(regs, reg_id)
    return me._meta(regs).get(me._map_len_key(reg_id))
  }
  set_map_len(regs, reg_id, len) {
    me._meta(regs).set(me._map_len_key(reg_id), len)
    return Result.Ok(0)
  }
  inc_map_len(regs, reg_id, delta) {
    local cur = me.get_map_len(regs, reg_id)
    local next = cur + delta
    if next < 0 { next = 0 }
    me.set_map_len(regs, reg_id, next)
    return next
  }
  _map_key_str(value) {
    // Keys for map meta should be string; centralize conversion
    return StringHelpers.int_to_str(value)
  }
  mark_map_entry(regs, reg_id, key_value) {
    local meta = me._meta(regs)
    local key = me._map_entry_key(reg_id, me._map_key_str(key_value))
    local existed = meta.get(key) != null
    meta.set(key, 1)
    return existed
  }
}
