discard """
  action: run
"""

import math, random, strutils
const consolePrefix = "jsCallbacks"

asm """
    var callback = []
    function regCallback (fn) { callback.push (fn); }
    function runCallbacks () {
        var result = "\n"
        var n = 0
        for (var fn in callback) {
            n += 1
            result += "("+String (n)+")"
            result += callback [fn] ()
            result += "\n"
        }
        return result
    }
    function print (text) { console.log (text); }
"""

proc consoleprint (str:cstring): void {.importc: "print", noDecl.}
proc print* (a: varargs[string, `$`]) = consoleprint "$1: $2" % [consolePrefix, join (a, " ")]

type CallbackProc {.importc.} = proc () : cstring

proc regCallback (fn:CallbackProc) {.importc.}
proc runCallbacks ():cstring {.importc.}

proc `*` (s:string, n:Natural) : string = s.repeat (n)

proc outer (i:Natural) : (string, int) =
    let c = $char (random (93) + 33)
    let n = random (40)
    let s = c * n
    proc inner () : cstring = ("[$1]" % $n) & s & " <--"
    regCallback (inner)
    return (s, n)

var expected = "\n"
for i in 1 .. 10:
    let (s, n) = outer (i)
    expected &= ("($1)[$2]" % [$i, $n]) & s & " <--"
    expected &= "\n"

let results = runCallbacks ()

doAssert(expected == results)
