/**
 * rbxl-lua-wait.test.js — тесты wait/task.wait через шедулер.
 */
import { LuaFactory } from 'wasmoon';
import { registerRobloxApi } from '../src/engine/roblox-shim.js';
import { RobloxScheduler } from '../src/engine/roblox-scheduler.js';

const SCENE = { primitives: {} };

async function run(luaSource, ticks = [0.5, 0.5, 0.5, 0.5, 0.5]) {
    const factory = new LuaFactory();
    const lua = await factory.createEngine();
    const sent = [];
    const send = (cmd, payload) => sent.push({ cmd, payload });
    registerRobloxApi(lua, { getSceneSnap: () => SCENE, targetPrimitiveId: null, send });
    const sched = new RobloxScheduler(lua);
    sched.install();

    await sched.spawnMain(luaSource);
    for (const dt of ticks) {
        await sched.tick(dt);
    }
    lua.global.close();
    return sent.filter(s => s.cmd === 'log').map(s => s.payload);
}

const TESTS = [
    {
        name: 'wait(0) — мгновенный',
        lua: `
            print("before")
            wait(0)
            print("after")
        `,
        expect: ['before', 'after'],
    },
    {
        name: 'wait(1) — резюм после tick',
        lua: `
            print("step1")
            wait(1)
            print("step2")
        `,
        ticks: [0.5, 0.5, 0.5],   // 1.5 сек суммарно
        expect: ['step1', 'step2'],
    },
    {
        name: 'task.wait(0.5)',
        lua: `
            print("a")
            task.wait(0.5)
            print("b")
        `,
        ticks: [0.5, 0.5],
        expect: ['a', 'b'],
    },
    {
        name: 'несколько wait подряд',
        lua: `
            print("p1")
            wait(0.5)
            print("p2")
            wait(0.5)
            print("p3")
        `,
        ticks: [0.5, 0.5, 0.5, 0.5],   // 2 сек
        expect: ['p1', 'p2', 'p3'],
    },
    {
        name: 'task.delay (не блокирует)',
        lua: `
            print("immediate")
            task.delay(0.3, function() print("delayed") end)
            print("after delay-call")
        `,
        ticks: [0.5],
        expect: ['immediate', 'after delay-call', 'delayed'],
    },
];

(async () => {
    let passed = 0, failed = 0;
    for (const t of TESTS) {
        try {
            const logs = await run(t.lua, t.ticks);
            const texts = logs.map(l => l.text);
            const ok = JSON.stringify(texts) === JSON.stringify(t.expect);
            if (ok) {
                console.log(`✓ ${t.name}`);
                passed++;
            } else {
                console.log(`✗ ${t.name}`);
                console.log(`    expected: ${JSON.stringify(t.expect)}`);
                console.log(`    got:      ${JSON.stringify(texts)}`);
                failed++;
            }
        } catch (e) {
            console.log(`✗ ${t.name} — exception: ${e}`);
            failed++;
        }
    }
    console.log(`\n${passed} passed, ${failed} failed`);
    process.exit(failed > 0 ? 1 : 0);
})();
