import Process from "process";
import { StartWASM2, Hub } from "./node.js";
import { StartMixCompiler, WaitForMixCompiler } from "@remix_labs/mixc-starter";
import { MixcoreWasm, MixcoreWasmApi } from "mixcore";
import { mixcoreWasmCode } from './mixcore-wasm-main.js';
import { WASI, OpenFile, File, Directory, PreopenDirectory, ConsoleStdout } from "@bjorn3/browser_wasi_shim";
function importCode(base64) {
    let binstr = atob(base64);
    let code = new Uint8Array(binstr.length);
    for (let i = 0; i < binstr.length; i++)
        code[i] = binstr.charCodeAt(i);
    return code;
}
let mixcoreWasm = importCode(mixcoreWasmCode);

if (Process.stdout._handle)
    Process.stdout._handle.setBlocking(true);
if (Process.stderr._handle)
    Process.stderr._handle.setBlocking(true);
Process.on("SIGINT", () => {
    console.log("SIGINT");
    Process.exit(1);
});
Process.on("SIGHUP", () => {
    console.log("SIGHUP");
    Process.exit(1);
});
globalThis.ThisIsNode = true;
let variant = Process.env["MIX_MACHINE_VARIANT"] || "JS";
let id = Process.env["MIX_MQTT_VMID"] || "prototest";
let baseURL = Process.env["MIX_BASEURL"];
let mqttURL = Process.env["MIX_MQTT_URL"] || (baseURL ? baseURL + "/x/broker.ws" : "ws://localhost:9025/");
baseURL = baseURL || "http://localhost:8001";
if (mqttURL.startsWith("http:")) {
    mqttURL = "ws:" + mqttURL.substring(5);
}
if (mqttURL.startsWith("https:")) {
    mqttURL = "wss:" + mqttURL.substring(5);
}
let mqttUser = Process.env["MIX_MQTT_USER"] || "dummy";
let mqttToken = Process.env["MIX_MQTT_TOKEN"] || "";
let noOutputViaMQTT = Process.env["MIX_MQTT_NO_OUTPUT"] !== undefined;
let with_mixc = !!(Process.env["MIXC_ENABLE"]);
console.log("Machine params: variant=" + variant + " baseURL=" + baseURL, " mqttURL=" + mqttURL, " mqttUser=" + mqttUser, " mqttToken=" + mqttToken, " id=" + id, " noOutputViaMQTT=" + noOutputViaMQTT, " withMixc=" + with_mixc);
let protoquery = Process.env["PROTOQUERY_ROOT"] || "";
let wasm_base = Process.env["MIX_WASM_BASE"] || "file://" + protoquery + "/wasm-build/artifacts/lib/wasm32-unknown-unknown";
let w = new Hub.Worker();
globalThis.GROOVEBOX_ALLOW_INSECURE_HTTP = true;

let DB_DIR = "db";
let wasi = new WASI([], [], [
    new OpenFile(new File([])),
    ConsoleStdout.lineBuffered(msg => console.log(`[WASI stdout] ${msg}`)),
    ConsoleStdout.lineBuffered(msg => console.warn(`[WASI stderr] ${msg}`)),
    new PreopenDirectory(".", new Map([[DB_DIR, new Directory(new Map())]]))
]);
MixcoreWasmApi.create(mixcoreWasm, wasi).then(mixcoreWasmApi => {
    let mixcore = MixcoreWasm.create(DB_DIR, "compiler-testing", "test@user", mixcoreWasmApi);
    let mixcoreConfig = { kind: "mixcore", mixcore };
    w.configure({wsURL: mqttURL, user:mqttUser, token:mqttToken}).then(resp => {
        if (variant == "BYTE") variant = "QCODE";
        switch(variant) {
        case "WASM":
        case "WAT":
        case "QCODE":
            let startVM = (_ => {
                MixSetMask(64 + 256 + 512 + 1024);
                StartWASM2(w, {
                    baseURL: baseURL,
                    org: "local",
                    workspace: "local",
                    vmID: id,
                    user: mqttUser,
                    token: mqttToken,
                    noOutputViaMQTT: noOutputViaMQTT,
                    machType: variant,
                    localFFIs: {},
                    mixcore: mixcoreConfig,
                });
            });
            if (with_mixc) {
                let mixcConfig = {
                    org: "local",
                    workspace: "local",
                    wasm_base: wasm_base
                };
                StartMixCompiler(w, mixcConfig).then(startVM);
            } else {
                startVM()
            };
            break
        default:
            throw(new Error("unknown MIX_MACHINE_VARIANT: " + variant))
        }
    })
});
