var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { getWorkerMessageAPI } from "./worker-messages";
import * as ZNM from "./zappar-cv";
const ctx = self;
let launchHandler = (evt) => {
    if (evt && evt.data && evt.data.t === "wasm") {
        let url = location.href.startsWith("blob") ? evt.data.url : new URL("./zappar-cv.wasm", import.meta.url).toString();
        launchCeresWorker(url, evt.data.module, evt.data.port, evt.data.instance);
        ctx.removeEventListener("message", launchHandler);
    }
};
ctx.addEventListener("message", launchHandler);
export function launchCeresWorker(wasmUrl, module, port, instance) {
    return __awaiter(this, void 0, void 0, function* () {
        let mod = ZNM.default({
            locateFile: (path, prefix) => {
                if (path.endsWith("zappar-cv.wasm")) {
                    return wasmUrl;
                }
                return prefix + path;
            },
            instantiateWasm: (imports, successCallback) => {
                const instance = new WebAssembly.Instance(module, imports);
                successCallback(instance);
                return instance.exports;
            },
            onRuntimeInitialized: () => {
                const ceres_worker = mod.cwrap('ceres_worker', null, ['number']);
                const messageAPI = getWorkerMessageAPI(mod);
                port.addEventListener('message', evt => {
                    if (evt.data.t !== 'msgsend')
                        return;
                    const data = evt.data.data;
                    const reference = evt.data.reference;
                    const ptr = mod._malloc(data.byteLength);
                    mod.HEAPU8.set(data, ptr);
                    messageAPI.worker_message_receive(reference, data.byteLength, ptr, instance);
                    mod._free(ptr);
                    ceres_worker(instance);
                    const toSend = messageAPI.worker_message_send_count();
                    for (let i = 0; i < toSend; i++) {
                        const reference = messageAPI.worker_message_send_reference(i);
                        const dataSize = messageAPI.worker_message_send_data_size(i);
                        const dataPtr = messageAPI.worker_message_send_data(i);
                        const data = mod.HEAPU8.slice(dataPtr, dataPtr + dataSize);
                        port.postMessage({
                            t: 'msgrec',
                            data,
                            reference
                        }, [data.buffer]);
                    }
                    messageAPI.worker_message_send_clear();
                });
                port.start();
            }
        });
    });
}
;
