/**
 * @license
 * Copyright 2015 The Emscripten Authors
 * SPDX-License-Identifier: MIT
 */

// Pthread Web Worker handling code.
// This code runs only on pthread web workers and handles pthread setup
// and communication with the main thread via postMessage.

#if ASSERTIONS
// Unique ID of the current pthread worker (zero on non-pthread-workers
// including the main thread).
var workerID = 0;
#endif

#if MAIN_MODULE
// Map of modules to be shared with new threads.  This gets populated by the
// main thread and shared with all new workers via the initial `load` message.
var sharedModules = {};
#endif

var startWorker;

if (ENVIRONMENT_IS_PTHREAD) {
  // Thread-local guard variable for one-time init of the JS state
  var initializedJS = false;

#if LOAD_SOURCE_MAP
  // When using postMessage to send an object, it is processed by the structured
  // clone algorithm.  The prototype, and hence methods, on that object is then
  // lost. This function adds back the lost prototype.  This does not work with
  // nested objects that has prototypes, but it suffices for WasmSourceMap.
  function resetPrototype(constructor, attrs) {
    var object = Object.create(constructor.prototype);
    return Object.assign(object, attrs);
  }
#endif

  // Turn unhandled rejected promises into errors so that the main thread will be
  // notified about them.
  self.onunhandledrejection = (e) => { throw e.reason || e; };

  {{{ asyncIf(ASYNCIFY == 2 || MAIN_MODULE) }}}function handleMessage(e) {
    try {
      var msgData = e.data;
      //dbg('msgData: ' + Object.keys(msgData));
      var cmd = msgData.cmd;
      if (cmd == {{{ CMD_LOAD }}}) { // Preload command that is called once per worker to parse and load the Emscripten code.
#if ASSERTIONS
        workerID = msgData.workerID;
#endif
#if PTHREADS_DEBUG
        dbg('worker: loading module')
#endif

        // Until we initialize the runtime, queue up any further incoming messages.
        let messageQueue = [];
        self.onmessage = (e) => messageQueue.push(e);

        // And add a callback for when the runtime is initialized.
        startWorker = () => {
          // Notify the main thread that this thread has loaded.
          postMessage({ cmd: {{{ CMD_LOADED }}} });
          // Process any messages that were queued before the thread was ready.
          for (let msg of messageQueue) {
            handleMessage(msg);
          }
          // Restore the real message handler.
          self.onmessage = handleMessage;
        };

#if MAIN_MODULE
        dynamicLibraries = msgData.dynamicLibraries;
        sharedModules = msgData.sharedModules;
#if RUNTIME_DEBUG
        dbg(`worker: received ${Object.keys(msgData.sharedModules).length} shared modules: ${Object.keys(msgData.sharedModules)}`);
#endif
#endif

        // Use `const` here to ensure that the variable is scoped only to
        // that iteration, allowing safe reference from a closure.
        for (const handler of msgData.handlers) {
          // If the main module has a handler for a certain event, but no
          // handler exists on the pthread worker, then proxy that handler
          // back to the main thread.
          if (!Module[handler] || Module[handler].proxy) {
#if RUNTIME_DEBUG
            dbg(`worker: installer proxying handler: ${handler}`);
#endif
            Module[handler] = (...args) => {
#if RUNTIME_DEBUG
              dbg(`worker: calling handler on main thread: ${handler}`);
#endif
              postMessage({ cmd: {{{ CMD_CALL_HANDLER }}}, handler, args: args });
            }
            // Rebind the out / err handlers if needed
            if (handler == 'print') out = Module[handler];
            if (handler == 'printErr') err = Module[handler];
          }
#if RUNTIME_DEBUG
          else dbg(`worker: using thread-local handler: ${handler}`);
#endif
        }

#if !WASM_ESM_INTEGRATION
        wasmMemory = msgData.wasmMemory;
        updateMemoryViews();
#endif

#if LOAD_SOURCE_MAP
        wasmSourceMap = resetPrototype(WasmSourceMap, msgData.wasmSourceMap);
#endif

#if SHARED_WASMGC
        __shared_heap_root.value = msgData.sharedHeapRootVal;
#endif

#if !WASM_ESM_INTEGRATION
#if MINIMAL_RUNTIME
        // Pass the shared Wasm module in the Module object for MINIMAL_RUNTIME.
        Module['wasm'] = msgData.wasmModule;
        loadModule();
#else
        wasmModule = msgData.wasmModule;
#if MODULARIZE == 'instance'
        init();
#else
        {{{ awaitIf(MAIN_MODULE) }}}createWasm();
        run();
#endif
#endif // MINIMAL_RUNTIME
#endif
#if !MINIMAL_RUNTIME
        startWorker();
#endif
      } else if (cmd == {{{ CMD_RUN }}}) {
#if ASSERTIONS
        assert(msgData.pthread_ptr);
        assert(wasmMemory, "CMD_RUN received before CMD_LOAD");
#endif
        // Call inside JS module to set up the stack frame for this pthread in JS module scope.
        // This needs to be the first thing that we do, as we cannot call to any C/C++ functions
        // until the thread stack is initialized.
        establishStackSpace(msgData.pthread_ptr);

        // Pass the thread address to wasm to store it for fast access.
        __emscripten_thread_init(msgData.pthread_ptr, /*is_main=*/0, /*is_runtime=*/0, /*can_block=*/1, 0, 0);

#if OFFSCREENCANVAS_SUPPORT
        PThread.receiveOffscreenCanvases(msgData);
#endif
        PThread.threadInitTLS();

        // Await mailbox notifications with `Atomics.waitAsync` so we can start
        // using the fast `Atomics.notify` notification path.
        __emscripten_thread_mailbox_await(msgData.pthread_ptr);

        if (!initializedJS) {
#if EMBIND
#if PTHREADS_DEBUG
          dbg(`worker: Pthread 0x${_pthread_self().toString(16)} initializing embind.`);
#endif
          // Embind must initialize itself on all threads, as it generates support JS.
          // We only do this once per worker since they get reused
          __embind_initialize_bindings();
#endif // EMBIND
          initializedJS = true;
        }

        try {
          {{{ awaitIf(ASYNCIFY == 2) }}}invokeEntryPoint(msgData.start_routine, msgData.arg);
        } catch(ex) {
          if (ex != 'unwind') {
            // The pthread "crashed".  Do not call `_emscripten_thread_exit` (which
            // would make this thread joinable).  Instead, re-throw the exception
            // and let the top level handler propagate it back to the main thread.
            throw ex;
          }
#if RUNTIME_DEBUG
          dbg(`worker: Pthread 0x${_pthread_self().toString(16)} completed its main entry point with an 'unwind', keeping the worker alive for asynchronous operation.`);
#endif
        }
      } else if (cmd == {{{ CMD_CHECK_MAILBOX }}}) {
        if (initializedJS) {
          checkMailbox();
        }
      } else if (cmd) {
        // The received message looks like something that should be handled by this message
        // handler, (since there is a cmd field present), but is not one of the
        // recognized commands:
        err(`worker: received unknown command ${cmd}`);
        err(msgData);
      }
    } catch(ex) {
#if ASSERTIONS
      err(`worker: onmessage() captured an uncaught exception: ${ex}`);
      if (ex?.stack) err(ex.stack);
#endif
      if (runtimeInitialized) __emscripten_thread_crashed();
      throw ex;
    }
  };

  self.onmessage = handleMessage;

} // ENVIRONMENT_IS_PTHREAD
