
@ignore_imut
@ignore_access

use valk:gc
use valk:coro
use valk:core

fn __valk_main__(argc: i32, argv: ptr) i32 $entrance {
    // Init
    gc:stack_top = gc:stack_root
    gc:thread_init(true)

    //
    @allocas

    //
    gc:mem_usage_shared = 0
    gc:mem_usage_peak = 0

    // Args
    let args = Array[String].new(8);
    let i = 0
    while i < argc {
        let arg = @ptrv(argv, cstring, i++)
        args.append(arg)
    }

    core:cli_args = args

    // Store globals & Set default value
    #loop globals G T
    G = @global_default_value(G)
    #if is_gc_type(T)
    gc:gc.globals.add_ptr(@ref(G))
    #end
    #end

    gc:gc.disable = false

    // Run
    #if TEST
        let main_coro = (co valk_run_all_tests()).@cast(coro:Coro)
    #else
        let main_coro = (co main(args)).@cast(coro:Coro)
    #end

    coro:Coro.loop(main_coro)

    return 0
}

#if TEST
fn valk_run_all_tests() {
    let results = core:TestResults{}
    let tests = Array[coro:Coro].new(64)

    #loop tests as test_func
    tests.append((co test_func(results)).@cast(coro:Coro))
    #end

    each tests as test {
        coro:await_coro(test)
    }

    results.print()

    if !results.passed() {
        exit(1)
    }
}
#end
