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

//
// Async support via ASYNCIFY
//

addToLibrary({
  // error handling

  $runAndAbortIfError: (func) => {
    try {
      return func();
    } catch (e) {
      abort(e);
    }
  },

#if ASYNCIFY
  $Asyncify__deps: ['$runAndAbortIfError', '$callUserCallback',
#if ASSERTIONS
    '$createNamedFunction',
#endif
#if !MINIMAL_RUNTIME
    '$runtimeKeepalivePush', '$runtimeKeepalivePop',
#endif
#if ASYNCIFY == 1
    // Needed by allocateData and handleSleep respectively
    'malloc', 'free',
#endif
  ],

  $Asyncify: {
    //
    // Asyncify code that is shared between mode 1 (original) and mode 2 (JSPI).
    //
#if ASYNCIFY == 1 && MEMORY64
    rewindArguments: new Map(),
#endif
    instrumentWasmImports(imports) {
#if EMBIND_GEN_MODE
      // Instrumenting is not needed when generating code.
      return imports;
#endif
#if ASYNCIFY_DEBUG
      dbg('asyncify instrumenting imports');
#endif
#if ASSERTIONS && ASYNCIFY == 2
      assert('Suspending' in WebAssembly, 'JSPI not supported by current environment. Perhaps it needs to be enabled via flags?');
#endif
      var importPattern = {{{ new RegExp(`^(${ASYNCIFY_IMPORTS_EXCEPT_JS_LIBS.map(x => x.split('.')[1]).join('|').replace(/\*/g, '.*')})$`) }}};

      for (let [x, original] of Object.entries(imports)) {
        if (typeof original == 'function') {
          let isAsyncifyImport = original.isAsync || importPattern.test(x);
#if ASYNCIFY == 2
          // Wrap async imports with a suspending WebAssembly function.
          if (isAsyncifyImport) {
#if ASYNCIFY_DEBUG
            dbg('asyncify: suspendOnReturnedPromise for', x, original);
#endif
            imports[x] = original = new WebAssembly.Suspending(original);
          }
#endif
#if ASSERTIONS && ASYNCIFY != 2 // We cannot apply assertions with stack switching, as the imports must not be modified from suspender.suspendOnReturnedPromise TODO find a way
          imports[x] = (...args) => {
            var originalAsyncifyState = Asyncify.state;
            try {
              return original(...args);
            } finally {
              // Only asyncify-declared imports are allowed to change the
              // state.
              // Changing the state from normal to disabled is allowed (in any
              // function) as that is what shutdown does (and we don't have an
              // explicit list of shutdown imports).
              var changedToDisabled =
                    originalAsyncifyState === Asyncify.State.Normal &&
                    Asyncify.state        === Asyncify.State.Disabled;
              // invoke_* functions are allowed to change the state if we do
              // not ignore indirect calls.
              var ignoredInvoke = x.startsWith('invoke_') &&
                                  {{{ !ASYNCIFY_IGNORE_INDIRECT }}};
              if (Asyncify.state !== originalAsyncifyState &&
                  !isAsyncifyImport &&
                  !changedToDisabled &&
                  !ignoredInvoke) {
                abort(`import ${x} was not in ASYNCIFY_IMPORTS, but changed the state`);
              }
            }
          };
#if MAIN_MODULE
          // The dynamic library loader needs to be able to read .sig
          // properties, so that it knows function signatures when it adds
          // them to the table.
          imports[x].sig = original.sig;
#endif // MAIN_MODULE
#endif // ASSERTIONS
        }
      }
    },
#if ASYNCIFY == 1 && MEMORY64
    saveRewindArguments(func, passedArguments) {
      return Asyncify.rewindArguments.set(func, Array.from(passedArguments));
    },
    restoreRewindArguments(func) {
#if ASSERTIONS
      assert(Asyncify.rewindArguments.has(func));
#endif
      return Asyncify.rewindArguments.get(func);
    },
#endif

#if ASYNCIFY == 1
    instrumentFunction(original) {
      var wrapper = (...args) => {
#if ASYNCIFY_DEBUG >= 2
        dbg(`ASYNCIFY: ${'  '.repeat(Asyncify.exportCallStack.length)} try ${original}`);
#endif
        Asyncify.exportCallStack.push(original);
        try {
#if MEMORY64
          Asyncify.saveRewindArguments(original, args);
#endif
          return original(...args);
        } finally {
          if (!ABORT) {
            var top = Asyncify.exportCallStack.pop();
#if ASSERTIONS
            assert(top === original);
#endif
#if ASYNCIFY_DEBUG >= 2
            dbg(`ASYNCIFY: ${'  '.repeat(Asyncify.exportCallStack.length)} finally ${original}`);
#endif
            Asyncify.maybeStopUnwind();
          }
        }
      };
      Asyncify.funcWrappers.set(original, wrapper);
#if MAIN_MODULE
      wrapper.orig = original;
#endif
#if ASSERTIONS
      wrapper = createNamedFunction(`__asyncify_wrapper_${original.name}`, wrapper);
#endif
      return wrapper;
    },
#endif // ASYNCIFY == 1

    instrumentWasmExports(exports) {
#if EMBIND_GEN_MODE
      // Instrumenting is not needed when generating code.
      return exports;
#endif
#if ASYNCIFY_DEBUG
      dbg('asyncify instrumenting exports');
#endif
#if ASYNCIFY == 2
      var exportPattern = {{{ new RegExp(`^(${ASYNCIFY_EXPORTS.join('|').replace(/\*/g, '.*')})$`) }}};
      Asyncify.asyncExports = new Set();
#endif
      var ret = {};
      for (let [x, original] of Object.entries(exports)) {
        if (typeof original == 'function') {
 #if ASYNCIFY == 2
          // Wrap all exports with a promising WebAssembly function.
          let isAsyncifyExport = exportPattern.test(x);
          if (isAsyncifyExport) {
            Asyncify.asyncExports.add(original);
            original = Asyncify.makeAsyncFunction(original);
          }
          ret[x] = original;
#else
          var wrapper = Asyncify.instrumentFunction(original);
          ret[x] = wrapper;
#endif
        } else {
          ret[x] = original;
        }
      }
      return ret;
    },

#if ASYNCIFY == 1
    //
    // Original implementation of Asyncify.
    //
    State: {
      Normal: 0,
      Unwinding: 1,
      Rewinding: 2,
      Disabled: 3,
    },
    state: 0,
    StackSize: {{{ ASYNCIFY_STACK_SIZE }}},
    currData: null,
    // The return value passed to wakeUp() in
    // Asyncify.handleSleep((wakeUp) => {...}) is stored here,
    // so we can return it later from the C function that called
    // Asyncify.handleSleep() after rewinding finishes.
    handleSleepReturnValue: 0,
    // We must track which wasm exports are called into and
    // exited, so that we know where the call stack began,
    // which is where we must call to rewind it.
    // This list contains the original Wasm exports.
    exportCallStack: [],
    callstackFuncToId: new Map(),
    callStackIdToFunc: new Map(),
    // Maps wasm functions to their corresponding wrapper function.
    funcWrappers: new Map(),
    callStackId: 0,
    asyncPromiseHandlers: null, // { resolve, reject } pair for when *all* asynchronicity is done
    sleepCallbacks: [], // functions to call every time we sleep

    getCallStackId(func) {
#if ASSERTIONS
      assert(func);
#endif
      if (!Asyncify.callstackFuncToId.has(func)) {
        var id = Asyncify.callStackId++;
        Asyncify.callstackFuncToId.set(func, id);
        Asyncify.callStackIdToFunc.set(id, func);
      }
      return Asyncify.callstackFuncToId.get(func);
    },

    maybeStopUnwind() {
#if ASYNCIFY_DEBUG
      dbg('ASYNCIFY: maybe stop unwind', Asyncify.exportCallStack);
#endif
      if (Asyncify.currData &&
          Asyncify.state === Asyncify.State.Unwinding &&
          !Asyncify.exportCallStack.length) {
        // We just finished unwinding.
        // Be sure to set the state before calling any other functions to avoid
        // possible infinite recursion here (For example in debug pthread builds
        // the dbg() function itself can call back into WebAssembly to get the
        // current pthread_self() pointer).
        Asyncify.state = Asyncify.State.Normal;
#if ASYNCIFY_DEBUG
        dbg('ASYNCIFY: stop unwind');
#endif
        {{{ runtimeKeepalivePush(); }}}
        // Keep the runtime alive so that a re-wind can be done later.
        runAndAbortIfError(_asyncify_stop_unwind);
        if (typeof Fibers != 'undefined') {
          Fibers.trampoline();
        }
      }
    },

    whenDone() {
#if ASSERTIONS
      assert(Asyncify.currData, 'tried to wait for an async operation when none is in progress');
      assert(!Asyncify.asyncPromiseHandlers, 'cannot have multiple async operations in flight at once');
#endif
      return new Promise((resolve, reject) => {
        Asyncify.asyncPromiseHandlers = { resolve, reject };
      });
    },

    allocateData() {
      // An asyncify data structure has three fields:
      //  0  current stack pos
      //  4  max stack pos
      //  8  id of function at bottom of the call stack (callStackIdToFunc[id] == wasm func)
      //
      // The Asyncify ABI only interprets the first two fields, the rest is for the runtime.
      // We also embed a stack in the same memory region here, right next to the structure.
      // This struct is also defined as asyncify_data_t in emscripten/fiber.h
      var ptr = _malloc({{{ C_STRUCTS.asyncify_data_s.__size__ }}} + Asyncify.StackSize);
      Asyncify.setDataHeader(ptr, ptr + {{{ C_STRUCTS.asyncify_data_s.__size__ }}}, Asyncify.StackSize);
      Asyncify.setDataRewindFunc(ptr);
      return ptr;
    },

    setDataHeader(ptr, stack, stackSize) {
      {{{ makeSetValue('ptr', C_STRUCTS.asyncify_data_s.stack_ptr, 'stack', '*') }}};
      {{{ makeSetValue('ptr', C_STRUCTS.asyncify_data_s.stack_limit, 'stack + stackSize', '*') }}};
    },

    setDataRewindFunc(ptr) {
      var bottomOfCallStack = Asyncify.exportCallStack[0];
#if ASYNCIFY_DEBUG >= 2
      dbg(`ASYNCIFY: setDataRewindFunc(${ptr}), bottomOfCallStack is`, bottomOfCallStack, new Error().stack);
#endif
#if ASSERTIONS
      assert(bottomOfCallStack, 'exportCallStack is empty');
#endif
      var rewindId = Asyncify.getCallStackId(bottomOfCallStack);
      {{{ makeSetValue('ptr', C_STRUCTS.asyncify_data_s.rewind_id, 'rewindId', 'i32') }}};
    },

    getDataRewindFunc(ptr) {
      var id = {{{ makeGetValue('ptr', C_STRUCTS.asyncify_data_s.rewind_id, 'i32') }}};
      var func = Asyncify.callStackIdToFunc.get(id);
#if ASSERTIONS
      assert(func, `id ${id} not found in callStackIdToFunc`);
#endif
      return func;
    },

    doRewind(ptr) {
      var original = Asyncify.getDataRewindFunc(ptr);
#if ASYNCIFY_DEBUG
      dbg('ASYNCIFY: doRewind:', original);
#endif
      var func = Asyncify.funcWrappers.get(original);
#if ASSERTIONS
      assert(original);
      assert(func);
#endif
      // Once we have rewound and the stack we no longer need to artificially
      // keep the runtime alive.
      {{{ runtimeKeepalivePop(); }}}
#if MEMORY64
      // When re-winding, the arguments to a function are ignored.  For i32 arguments we
      // can just call the function with no args at all since the engine will produce zeros
      // for all arguments.  However, for i64 arguments we get `undefined cannot be converted to
      // BigInt`.
      func = func.bind(0, ...Asyncify.restoreRewindArguments(original));
#endif
      return callUserCallback(func);
    },

    // This receives a function to call to start the async operation, and
    // handles everything else for the user of this API. See emscripten_sleep()
    // and other async methods for simple examples of usage.
    handleSleep(startAsync) {
#if ASSERTIONS
      assert(Asyncify.state !== Asyncify.State.Disabled, 'handleSleep called after Asyncify was shut down');
#endif
      if (ABORT) return;
#if ASYNCIFY_DEBUG
      dbg(`ASYNCIFY: handleSleep ${Asyncify.state}`);
#endif
      if (Asyncify.state === Asyncify.State.Normal) {
        // Prepare to sleep. Call startAsync, and see what happens:
        // if the code decided to call our callback synchronously,
        // then no async operation was in fact begun, and we don't
        // need to do anything.
        var reachedCallback = false;
        var reachedAfterCallback = false;
        startAsync((handleSleepReturnValue = 0) => {
#if ASSERTIONS
          // old emterpretify API supported other stuff
          assert(['undefined', 'number', 'boolean', 'bigint'].includes(typeof handleSleepReturnValue), `invalid type for handleSleepReturnValue: '${typeof handleSleepReturnValue}'`);
#endif
          if (ABORT) return;
          Asyncify.handleSleepReturnValue = handleSleepReturnValue;
          reachedCallback = true;
          if (!reachedAfterCallback) {
            // We are happening synchronously, so no need for async.
            return;
          }
#if ASSERTIONS
          // This async operation did not happen synchronously, so we did
          // unwind. In that case there can be no compiled code on the stack,
          // as it might break later operations (we can rewind ok now, but if
          // we unwind again, we would unwind through the extra compiled code
          // too).
          assert(!Asyncify.exportCallStack.length, 'waking up (starting to rewind) must be done from JS, without compiled code on the stack');
#endif
#if ASYNCIFY_DEBUG
          dbg(`ASYNCIFY: start rewind ${Asyncify.currData}`);
#endif
          Asyncify.state = Asyncify.State.Rewinding;
          runAndAbortIfError(() => _asyncify_start_rewind(Asyncify.currData));
          if (typeof MainLoop != 'undefined' && MainLoop.func) {
            MainLoop.resume();
          }
          var asyncWasmReturnValue, isError = false;
          try {
            asyncWasmReturnValue = Asyncify.doRewind(Asyncify.currData);
          } catch (err) {
            asyncWasmReturnValue = err;
            isError = true;
          }
          // Track whether the return value was handled by any promise handlers.
          var handled = false;
          if (!Asyncify.currData) {
            // All asynchronous execution has finished.
            // `asyncWasmReturnValue` now contains the final
            // return value of the exported async WASM function.
            //
            // Note: `asyncWasmReturnValue` is distinct from
            // `Asyncify.handleSleepReturnValue`.
            // `Asyncify.handleSleepReturnValue` contains the return
            // value of the last C function to have executed
            // `Asyncify.handleSleep()`, whereas `asyncWasmReturnValue`
            // contains the return value of the exported WASM function
            // that may have called C functions that
            // call `Asyncify.handleSleep()`.
            var asyncPromiseHandlers = Asyncify.asyncPromiseHandlers;
            if (asyncPromiseHandlers) {
              Asyncify.asyncPromiseHandlers = null;
              (isError ? asyncPromiseHandlers.reject : asyncPromiseHandlers.resolve)(asyncWasmReturnValue);
              handled = true;
            }
          }
          if (isError && !handled) {
            // If there was an error and it was not handled by now, we have no choice but to
            // rethrow that error into the global scope where it can be caught only by
            // `onerror` or `onunhandledpromiserejection`.
            throw asyncWasmReturnValue;
          }
        });
        reachedAfterCallback = true;
        if (!reachedCallback) {
          // A true async operation was begun; start a sleep.
          Asyncify.state = Asyncify.State.Unwinding;
          // TODO: reuse, don't alloc/free every sleep
          Asyncify.currData = Asyncify.allocateData();
#if ASYNCIFY_DEBUG
          dbg(`ASYNCIFY: start unwind ${Asyncify.currData}`);
#endif
          if (typeof MainLoop != 'undefined' && MainLoop.func) {
            MainLoop.pause();
          }
          runAndAbortIfError(() => _asyncify_start_unwind(Asyncify.currData));
        }
      } else if (Asyncify.state === Asyncify.State.Rewinding) {
        // Stop a resume.
#if ASYNCIFY_DEBUG
        dbg('ASYNCIFY: stop rewind');
#endif
        Asyncify.state = Asyncify.State.Normal;
        runAndAbortIfError(_asyncify_stop_rewind);
        _free(Asyncify.currData);
        Asyncify.currData = null;
        // Call all sleep callbacks now that the sleep-resume is all done.
        Asyncify.sleepCallbacks.forEach(callUserCallback);
      } else {
        abort(`invalid state: ${Asyncify.state}`);
      }
      return Asyncify.handleSleepReturnValue;
    },

    // Unlike `handleSleep`, accepts a function returning a `Promise`
    // and uses the fulfilled value instead of passing in a separate callback.
    //
    // This is particularly useful for native JS `async` functions where the
    // returned value will "just work" and be passed back to C++.
    handleAsync: (startAsync) => Asyncify.handleSleep(async (wakeUp) => {
      // TODO: add error handling as a second param when handleSleep implements it.
      wakeUp(await startAsync());
    }),

#elif ASYNCIFY == 2
    //
    // JSPI implementation of Asyncify.
    //

    // Stores all the exported raw Wasm functions that are wrapped with async
    // WebAssembly.Functions.
    asyncExports: null,
    isAsyncExport(func) {
      return Asyncify.asyncExports?.has(func);
    },
    handleAsync: async (startAsync) => {
      {{{ runtimeKeepalivePush(); }}}
      try {
        return await startAsync();
      } finally {
        {{{ runtimeKeepalivePop(); }}}
      }
    },
    handleSleep: (startAsync) => Asyncify.handleAsync(() => new Promise(startAsync)),
    makeAsyncFunction(original) {
#if ASYNCIFY_DEBUG
      dbg('asyncify: makeAsyncFunction for', original);
#endif
      return WebAssembly.promising(original);
    },
#endif
  },

  emscripten_sleep__async: 'auto',
  emscripten_sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),

  emscripten_wget_data__deps: ['$asyncLoad', 'malloc'],
  emscripten_wget_data__async: 'auto',
  emscripten_wget_data: async (url, pbuffer, pnum, perror) => {
    /* no need for run dependency, this is async but will not do any prepare etc. step */
    try {
      const byteArray = await asyncLoad(UTF8ToString(url));
      // can only allocate the buffer after the wakeUp, not during an asyncing
      var buffer = _malloc(byteArray.length); // must be freed by caller!
      HEAPU8.set(byteArray, buffer);
      {{{ makeSetValue('pbuffer', 0, 'buffer', '*') }}};
      {{{ makeSetValue('pnum', 0, 'byteArray.length', 'i32') }}};
      {{{ makeSetValue('perror', 0, '0', 'i32') }}};
    } catch (err) {
      {{{ makeSetValue('perror', 0, '1', 'i32') }}};
    }
  },

  emscripten_scan_registers__deps: ['$safeSetTimeout'],
  emscripten_scan_registers__async: true,
  emscripten_scan_registers: (func) => {
    return Asyncify.handleSleep((wakeUp) => {
      // We must first unwind, so things are spilled to the stack. Then while
      // we are pausing we do the actual scan. After that we can resume. Note
      // how using a timeout here avoids unbounded call stack growth, which
      // could happen if we tried to scan the stack immediately after unwinding.
      safeSetTimeout(() => {
        var stackBegin = Asyncify.currData + {{{ C_STRUCTS.asyncify_data_s.__size__ }}};
        var stackEnd = {{{ makeGetValue('Asyncify.currData', 0, '*') }}};
        {{{ makeDynCall('vpp', 'func') }}}(stackBegin, stackEnd);
        wakeUp();
      }, 0);
    });
  },

  $Fibers__deps: ['$Asyncify', 'emscripten_stack_set_limits', '$stackRestore'],
  $Fibers: {
    nextFiber: 0,
    trampolineRunning: false,
    trampoline() {
      if (!Fibers.trampolineRunning && Fibers.nextFiber) {
        Fibers.trampolineRunning = true;
        do {
          var fiber = Fibers.nextFiber;
          Fibers.nextFiber = 0;
#if ASYNCIFY_DEBUG >= 2
          dbg('ASYNCIFY/FIBER: trampoline jump into fiber', fiber, new Error().stack);
#endif
          Fibers.finishContextSwitch(fiber);
        } while (Fibers.nextFiber);
        Fibers.trampolineRunning = false;
      }
    },
    /*
     * NOTE: This function is the asynchronous part of emscripten_fiber_swap.
     */
    finishContextSwitch(newFiber) {
      var stack_base = {{{ makeGetValue('newFiber', C_STRUCTS.emscripten_fiber_s.stack_base,  '*') }}};
      var stack_max =  {{{ makeGetValue('newFiber', C_STRUCTS.emscripten_fiber_s.stack_limit, '*') }}};
      _emscripten_stack_set_limits(stack_base, stack_max);

#if STACK_OVERFLOW_CHECK >= 2
      ___set_stack_limits(stack_base, stack_max);
#endif

      stackRestore({{{ makeGetValue('newFiber', C_STRUCTS.emscripten_fiber_s.stack_ptr,   '*') }}});

      var entryPoint = {{{ makeGetValue('newFiber', C_STRUCTS.emscripten_fiber_s.entry, '*') }}};

      if (entryPoint) {
#if STACK_OVERFLOW_CHECK
        writeStackCookie();
#endif
#if ASYNCIFY_DEBUG
        dbg('ASYNCIFY/FIBER: entering fiber', newFiber, 'for the first time');
#endif
        Asyncify.currData = null;
        {{{ makeSetValue('newFiber', C_STRUCTS.emscripten_fiber_s.entry, 0, '*') }}};

        var userData = {{{ makeGetValue('newFiber', C_STRUCTS.emscripten_fiber_s.user_data, '*') }}};
        {{{ makeDynCall('vp', 'entryPoint') }}}(userData);
      } else {
        var asyncifyData = newFiber + {{{ C_STRUCTS.emscripten_fiber_s.asyncify_data }}};
        Asyncify.currData = asyncifyData;

#if ASYNCIFY_DEBUG
        dbg('ASYNCIFY/FIBER: start rewind', asyncifyData, '(resuming fiber', newFiber, ')');
#endif
        Asyncify.state = Asyncify.State.Rewinding;
        _asyncify_start_rewind(asyncifyData);
        Asyncify.doRewind(asyncifyData);
      }
    },
  },

  emscripten_fiber_swap__deps: ['$Asyncify', '$Fibers', '$stackSave'],
  emscripten_fiber_swap__async: true,
  emscripten_fiber_swap: (oldFiber, newFiber) => {
    if (ABORT) return;
#if ASYNCIFY_DEBUG
    dbg('ASYNCIFY/FIBER: swap', oldFiber, '->', newFiber, 'state:', Asyncify.state);
#endif
    if (Asyncify.state === Asyncify.State.Normal) {
      Asyncify.state = Asyncify.State.Unwinding;

      var asyncifyData = oldFiber + {{{ C_STRUCTS.emscripten_fiber_s.asyncify_data }}};
      Asyncify.setDataRewindFunc(asyncifyData);
      Asyncify.currData = asyncifyData;

#if ASYNCIFY_DEBUG
      dbg('ASYNCIFY/FIBER: start unwind', asyncifyData);
#endif
      _asyncify_start_unwind(asyncifyData);

      var stackTop = stackSave();
      {{{ makeSetValue('oldFiber', C_STRUCTS.emscripten_fiber_s.stack_ptr, 'stackTop', '*') }}};

      Fibers.nextFiber = newFiber;
    } else {
#if ASSERTIONS
      assert(Asyncify.state === Asyncify.State.Rewinding);
#endif
#if ASYNCIFY_DEBUG
      dbg('ASYNCIFY/FIBER: stop rewind');
#endif
      Asyncify.state = Asyncify.State.Normal;
      _asyncify_stop_rewind();
      Asyncify.currData = null;
    }
  },
#else // ASYNCIFY
  emscripten_sleep: () => {
    abort('Please compile your program with async support in order to use asynchronous operations like emscripten_sleep');
  },
  emscripten_wget: (url, file) => {
    abort('Please compile your program with async support in order to use asynchronous operations like emscripten_wget');
  },
  emscripten_wget_data: (url, pbuffer, pnum, perror) => {
    abort('Please compile your program with async support in order to use asynchronous operations like emscripten_wget_data');
  },
  emscripten_scan_registers: (func) => {
    abort('Please compile your program with async support in order to use asynchronous operations like emscripten_scan_registers');
  },
  emscripten_fiber_swap: (oldFiber, newFiber) => {
    abort('Please compile your program with async support in order to use asynchronous operations like emscripten_fiber_swap');
  },
#endif // ASYNCIFY
});

if (ASYNCIFY) {
  extraLibraryFuncs.push('$Asyncify');
}
