// InstructionDispatcherBox - Dispatch instructions to specific handlers
// Single Responsibility: Extract op field and route to correct handler

using selfhost.shared.common.string_ops as StringOps
using selfhost.vm.boxes.result_box as Result
using selfhost.vm.hakorune-vm.json_field_extractor as JsonFieldExtractor
using selfhost.vm.hakorune-vm.value_manager as ValueManagerBox
using selfhost.vm.hakorune-vm.const_handler as ConstHandlerBox
using selfhost.vm.hakorune-vm.binop_handler as BinOpHandlerBox
using selfhost.vm.hakorune-vm.compare_handler as CompareHandlerBox
using selfhost.vm.hakorune-vm.copy_handler as CopyHandlerBox
using selfhost.vm.hakorune-vm.unaryop_handler as UnaryOpHandlerBox
using selfhost.vm.hakorune-vm.load_handler as LoadHandlerBox
using selfhost.vm.hakorune-vm.store_handler as StoreHandlerBox
using selfhost.vm.hakorune-vm.nop_handler as NopHandlerBox
using selfhost.vm.hakorune-vm.safepoint_handler as SafepointHandlerBox
using selfhost.vm.hakorune-vm.barrier_handler as BarrierHandlerBox
using selfhost.vm.hakorune-vm.typeop_handler as TypeOpHandlerBox
using selfhost.vm.hakorune-vm.mircall_handler as MirCallHandlerBox
using selfhost.vm.hakorune-vm.boxcall_handler as BoxCallHandlerBox
using selfhost.vm.hakorune-vm.newbox_handler as NewBoxHandlerBox
using selfhost.vm.hakorune-vm.ret_value_loader as RetValueLoaderBox

static box InstructionDispatcherBox {
  // Dispatch instruction based on op field
  // inst_json: MIR instruction JSON (e.g., '{"op":"const","dst":1,...}')
  // regs: register MapBox
  // mem: memory MapBox
  // Returns: Result.Ok(0) or Result.Err(message)
  dispatch(inst_json, regs, mem) {
    // Extract op field
    local key_op = "\"op\":\""
    local op_start = inst_json.indexOf(key_op)
    if op_start < 0 {
      return Result.Err("op field not found")
    }
    op_start = op_start + key_op.length()

    local op_end = StringOps.index_of_from(inst_json, "\"", op_start)
    if op_end < 0 {
      return Result.Err("op field end not found")
    }

    local op = inst_json.substring(op_start, op_end)

    // Skip PHI (handled separately at block start)
    if op == "phi" {
      return Result.Ok(0)
    }

    // @match instruction dispatch to handler boxes
    return match op {
      "const" => ConstHandlerBox.handle(inst_json, regs)
      "unaryop" => UnaryOpHandlerBox.handle(inst_json, regs)
      "binop" => BinOpHandlerBox.handle(inst_json, regs)
      "compare" => CompareHandlerBox.handle(inst_json, regs)
      "load" => LoadHandlerBox.handle(inst_json, regs, mem)
      "store" => StoreHandlerBox.handle(inst_json, regs, mem)
      "ret" => RetValueLoaderBox.load_from_instruction(inst_json, regs)
      "copy" => CopyHandlerBox.handle(inst_json, regs)
      "nop" => NopHandlerBox.handle(inst_json, regs, mem)
      "safepoint" => SafepointHandlerBox.handle(inst_json, regs, mem)
      "barrier" => BarrierHandlerBox.handle(inst_json, regs, mem)
      "typeop" => TypeOpHandlerBox.handle(inst_json, regs, mem)
      "mir_call" => MirCallHandlerBox.handle(inst_json, regs, mem)
      "boxcall" => BoxCallHandlerBox.handle(inst_json, regs)
      "newbox" => NewBoxHandlerBox.handle(inst_json, regs)
      _ => Result.Err("unsupported instruction: " + op)
    }
  }
}
