# import pylib # for f-strings
import std/strformat

type
    ContextRef = ref object
        oid : int
        started : bool
        remaining : int
        ticker : int
        callpath : seq[int]

var
    ctx : ContextRef
new(ctx)


type
    Task = iterator (ticker: int)

var
    next_iter : array[2, Task]


iterator a1(ticker: int) {.closure.} =
    echo fmt"a1: A {ctx.ticker=} {ctx.oid=}"
    yield
    echo fmt"a1: B {ctx.ticker=} {ctx.oid=}"
    yield
    echo fmt"a1: C {ctx.ticker=} {ctx.oid=}"
    yield
    echo fmt"a1: D {ctx.ticker=} {ctx.oid=}"
    yield

iterator a2(ticker: int) {.closure.} =
    echo fmt"a2: A2 {ctx.ticker=} {ctx.oid=}"
    yield
    echo fmt"a2: B2 {ctx.ticker=} {ctx.oid=}"
    yield



proc runTasks(tasks: varargs[Task]):int =
    if not ctx.started:
        ctx.remaining = tasks.len+1
        ctx.ticker = 0
        ctx.started = true
        for assign in 0..<tasks.len:
            next_iter[assign] = tasks[assign]

    block: # <-- does not work, iterator are reset each pass
    #while ctx.remaining>0: # ok but blocking ...
        ctx.oid = ctx.ticker mod tasks.len

        if finished(next_iter[ctx.oid]):
            dec ctx.remaining

        next_iter[ctx.oid](ctx.ticker)

        inc(ctx.ticker)

    return ctx.remaining

proc setup():void =
    ctx.ticker = 0
    ctx.remaining = 0
    ctx.started = false

var i:int

proc loop():int =
    i = 0
    while runTasks(a1,a2)>0:
        echo(fmt"{ctx.remaining=}")
        i += 1
        if i > 10:
            break
    return 0

when defined(wasi):
    proc main(argc: cint, args: ptr ptr char): cint {.exportC:"main".} =
        echo "WASI startup"
        setup()
        # this one should be called repeatably by wasi polyfill.
        while loop()>0:
            discard
else:
    echo "main startup"
    setup()
    while loop()>0:
        discard