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

#if FETCH_STREAMING
/**
 * A class that mimics the XMLHttpRequest API using the modern Fetch API.
 * This implementation is specifically tailored to only handle 'arraybuffer'
 * responses.
 */
class FetchXHR {
  // --- Public XHR Properties ---

  // Event Handlers
  onload = null;
  onerror = null;
  onprogress = null;
  onreadystatechange = null;
  ontimeout = null;

  // Request Configuration
  responseType = 'arraybuffer';
  withCredentials = false;
  timeout = 0; // Standard XHR timeout property

  // Response / State Properties
  readyState = 0; // 0: UNSENT
  response = null;
  responseURL = '';
  status = 0;
  statusText = '';

  // --- Internal Properties ---
  _method = '';
  _url = '';
  _headers = {};
  _abortController = null;
  _aborted = false;
  _responseHeaders = null;

  // When enabled the the data will be streamed using progress events. If the full result is needed
  // the data must be collected during the progress events.
  _streamData = false;

  // --- Private state management ---
  _changeReadyState(state) {
    this.readyState = state;
    this.onreadystatechange?.();
  }

  // --- Public XHR Methods ---

  /**
   * Initializes a request.
   * @param {string} method The HTTP request method (e.g., 'GET', 'POST').
   * @param {string} url The URL to send the request to.
   * @param {boolean} [async=true] This parameter is ignored as Fetch is always async.
   * @param {string|null} [user=null] The username for basic authentication.
   * @param {string|null} [password=null] The password for basic authentication.
   */
  open(method, url, async = true, user = null, password = null) {
    if (this.readyState !== 0 && this.readyState !== 4) {
      console.warn("FetchXHR.open() called while a request is in progress.");
      this.abort();
    }

    // Reset internal state for the new request
    this._method = method;
    this._url = url;
    this._headers = {};
    this._responseHeaders = null;

    // The async parameter is part of the XHR API but is an error here because
    // the Fetch API is inherently asynchronous and does not support synchronous requests.
    if (!async) {
      throw new Error("FetchXHR does not support synchronous requests.");
    }

    // Handle Basic Authentication if user/password are provided.
    // This creates a base64-encoded string and sets the Authorization header.
    if (user) {
      const credentials = btoa(`${user}:${password ?? ''}`);
      this._headers['Authorization'] = `Basic ${credentials}`;
    }

    this._changeReadyState(1); // 1: OPENED
  }

  /**
   * Sets the value of an HTTP request header.
   * @param {string} header The name of the header.
   * @param {string} value The value of the header.
   */
  setRequestHeader(header, value) {
    if (this.readyState !== 1) {
      throw new Error('setRequestHeader can only be called when state is OPENED.');
    }
    this._headers[header] = value;
  }

  /**
   * This method is not effectively implemented because Fetch API relies on the
   * server's Content-Type header and does not support overriding the MIME type
   * on the client side in the same way as XHR.
   * @param {string} mimetype The MIME type to use.
   */
  overrideMimeType(mimetype) {
    throw new Error("overrideMimeType is not supported by the Fetch API and has no effect.");
  }

  /**
   * Returns a string containing all the response headers, separated by CRLF.
   * @returns {string} The response headers.
   */
  getAllResponseHeaders() {
    if (!this._responseHeaders) {
      return '';
    }

    let headersString = '';
    // The Headers object is iterable.
    for (const [key, value] of this._responseHeaders.entries()) {
      headersString += `${key}: ${value}\r\n`;
    }
    return headersString;
  }

  /**
   * Sends the request.
   * @param body The body of the request.
   */
  async send(body = null) {
    if (this.readyState !== 1) {
      throw new Error('send() can only be called when state is OPENED.');
    }

    this._abortController = new AbortController();
    const signal = this._abortController.signal;

    // Handle timeout
    let timeoutID;
    if (this.timeout > 0) {
      timeoutID = setTimeout(
        () => this._abortController.abort(new DOMException('The user aborted a request.', 'TimeoutError')),
        this.timeout
      );
    }

    const fetchOptions = {
      method: this._method,
      headers: this._headers,
      body: body,
      signal: signal,
      credentials: this.withCredentials ? 'include' : 'same-origin',
    };

    try {
      const response = await fetch(this._url, fetchOptions);

      // Populate response properties once headers are received
      this.status = response.status;
      this.statusText = response.statusText;
      this.responseURL = response.url;
      this._responseHeaders = response.headers;
      this._changeReadyState(2); // 2: HEADERS_RECEIVED

      // Start processing the body
      this._changeReadyState(3); // 3: LOADING

      if (!response.body) {
        throw new Error("Response has no body to read.");
      }

      const reader = response.body.getReader();
      const contentLength = +response.headers.get('Content-Length');

      let receivedLength = 0;
      // When streaming data don't collect all of the chunks into one large chunk. It's up to the
      // user to collect the data as it comes in.
      const chunks = this._streamData ? null : [];

      while (true) {
        const { done, value } = await reader.read();
        if (done) {
          break;
        }

        if (!this._streamData) {
          chunks.push(value);
        }
        receivedLength += value.length;

        if (this.onprogress) {
          // Convert to ArrayBuffer as requested by responseType.
          this.response = value.buffer;
          const progressEvent = {
            lengthComputable: contentLength > 0,
            loaded: receivedLength,
            total: contentLength
          };
          this.onprogress(progressEvent);
        }
      }

      if (this._streamData) {
        this.response = null;
      } else {
        // Combine chunks into a single Uint8Array.
        const allChunks = new Uint8Array(receivedLength);
        let position = 0;
        for (const chunk of chunks) {
          allChunks.set(chunk, position);
          position += chunk.length;
        }
        // Convert to ArrayBuffer as requested by responseType
        this.response = allChunks.buffer;
      }
    } catch (error) {
      this.statusText = error.message;

      if (error.name === 'AbortError') {
        // Do nothing.
      } else if (error.name === 'TimeoutError') {
        this.ontimeout?.();
      } else {
        // This is a network error
        this.onerror?.();
      }
    } finally {
      clearTimeout(timeoutID);
      if (!this._aborted) {
        this._changeReadyState(4); // 4: DONE
        // The XHR 'load' event fires for successful HTTP statuses (2xx) as well as
        // unsuccessful ones (4xx, 5xx). The 'error' event is for network failures.
        this.onload?.();
      }
    }
  }

  /**
   * Aborts the request if it has already been sent.
   */
  abort() {
    this._aborted = true;
    this.status = 0;
    this._changeReadyState(4); // 4: DONE
    this._abortController?.abort();
  }
}
#endif

var Fetch = {
  // HandleAllocator for XHR request object
  // xhrs: undefined,

  // The web worker that runs proxied file I/O requests. (this field is
  // populated on demand, start as undefined to save code size)
  // worker: undefined,

  // Specifies an instance to the IndexedDB database. The database is opened
  // as a preload step before the Emscripten application starts. (this field is
  // populated on demand, start as undefined to save code size)
  // dbInstance: undefined,

#if FETCH_SUPPORT_INDEXEDDB
  async openDatabase(dbname, dbversion) {
    return new Promise((resolve, reject) => {
      try {
#if FETCH_DEBUG
        dbg(`fetch: indexedDB.open(dbname="${dbname}", dbversion="${dbversion}");`);
#endif
        var openRequest = indexedDB.open(dbname, dbversion);
      } catch (e) {
        return reject(e);
      }

      openRequest.onupgradeneeded = (event) => {
#if FETCH_DEBUG
        dbg('fetch: IndexedDB upgrade needed. Clearing database.');
#endif
        var db = /** @type {IDBDatabase} */ (event.target.result);
        if (db.objectStoreNames.contains('FILES')) {
          db.deleteObjectStore('FILES');
        }
        db.createObjectStore('FILES');
      };
      openRequest.onsuccess = (event) => resolve(event.target.result);
      openRequest.onerror = reject;
    });
  },
#endif

  async init() {
    Fetch.xhrs = new HandleAllocator();
#if FETCH_SUPPORT_INDEXEDDB
#if PTHREADS
    if (ENVIRONMENT_IS_PTHREAD) return;
#endif

    addRunDependency('library_fetch_init');
    try {
      var db = await Fetch.openDatabase('emscripten_filesystem', 1);
#if FETCH_DEBUG
      dbg('fetch: IndexedDB successfully opened.');
#endif
      Fetch.dbInstance = db;
    } catch (e) {
#if FETCH_DEBUG
      dbg('fetch: IndexedDB open failed.');
#endif
      Fetch.dbInstance = false;
    } finally {
      removeRunDependency('library_fetch_init');
    }
#endif // ~FETCH_SUPPORT_INDEXEDDB
  }
}

#if FETCH_SUPPORT_INDEXEDDB
function fetchDeleteCachedData(db, fetch, onsuccess, onerror) {
  if (!db) {
#if FETCH_DEBUG
    dbg('fetch: IndexedDB not available!');
#endif
    onerror(fetch, 0, 'IndexedDB not available!');
    return;
  }

  var fetch_attr = fetch + {{{ C_STRUCTS.emscripten_fetch_t.__attributes }}};
  var path = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.destinationPath, '*') }}};
  path ||= {{{ makeGetValue('fetch', C_STRUCTS.emscripten_fetch_t.url, '*') }}};

  var pathStr = UTF8ToString(path);

  try {
    var transaction = db.transaction(['FILES'], 'readwrite');
    var packages = transaction.objectStore('FILES');
    var request = packages.delete(pathStr);
    request.onsuccess = (event) => {
      var value = event.target.result;
#if FETCH_DEBUG
      dbg(`fetch: Deleted file ${pathStr} from IndexedDB`);
#endif
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.data, 0, '*') }}};
      writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.numBytes }}}, 0);
      writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.dataOffset }}}, 0);
      writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.totalBytes }}}, 0);
      // Mimic XHR readyState 4 === 'DONE: The operation is complete'
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.readyState, 4, 'i16') }}};
      // Mimic XHR HTTP status code 200 "OK"
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.status, 200, 'i16') }}};
      stringToUTF8("OK", fetch + {{{ C_STRUCTS.emscripten_fetch_t.statusText }}}, 64);
      onsuccess(fetch, 0, value);
    };
    request.onerror = (error) => {
#if FETCH_DEBUG
      dbg(`fetch: Failed to delete file ${pathStr} from IndexedDB! error: ${error}`);
#endif
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.readyState, 4, 'i16') }}} // Mimic XHR readyState 4 === 'DONE: The operation is complete'
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.status, 404, 'i16') }}} // Mimic XHR HTTP status code 404 "Not Found"
      stringToUTF8("Not Found", fetch + {{{ C_STRUCTS.emscripten_fetch_t.statusText }}}, 64);
      onerror(fetch, 0, error);
    };
  } catch(e) {
#if FETCH_DEBUG
    dbg(`fetch: Failed to load file ${pathStr} from IndexedDB! Got exception ${e}`);
#endif
    onerror(fetch, 0, e);
  }
}

function fetchLoadCachedData(db, fetch, onsuccess, onerror) {
  if (!db) {
#if FETCH_DEBUG
    dbg('fetch: IndexedDB not available!');
#endif
    onerror(fetch, 0, 'IndexedDB not available!');
    return;
  }

  var fetch_attr = fetch + {{{ C_STRUCTS.emscripten_fetch_t.__attributes }}};
  var path = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.destinationPath, '*') }}};
  path ||= {{{ makeGetValue('fetch', C_STRUCTS.emscripten_fetch_t.url, '*') }}};
  var pathStr = UTF8ToString(path);

  try {
    var transaction = db.transaction(['FILES'], 'readonly');
    var packages = transaction.objectStore('FILES');
    var getRequest = packages.get(pathStr);
    getRequest.onsuccess = (event) => {
      if (event.target.result) {
        var value = event.target.result;
        var len = value.byteLength || value.length;
#if FETCH_DEBUG
        dbg(`fetch: Loaded file ${pathStr} from IndexedDB, length: ${len}`);
#endif
        // The data pointer malloc()ed here has the same lifetime as the emscripten_fetch_t structure itself has, and is
        // freed when emscripten_fetch_close() is called.
        var ptr = _malloc(len);
        HEAPU8.set(new Uint8Array(value), ptr);
        {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.data, 'ptr', '*') }}};
        writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.numBytes }}}, len);
        writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.dataOffset }}}, 0);
        writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.totalBytes }}}, len);
        {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.readyState, 4, 'i16') }}} // Mimic XHR readyState 4 === 'DONE: The operation is complete'
        {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.status, 200, 'i16') }}} // Mimic XHR HTTP status code 200 "OK"
        stringToUTF8("OK", fetch + {{{ C_STRUCTS.emscripten_fetch_t.statusText }}}, 64);
        onsuccess(fetch, 0, value);
      } else {
        // Succeeded to load, but the load came back with the value of undefined, treat that as an error since we never store undefined in db.
#if FETCH_DEBUG
        dbg(`fetch: File ${pathStr} not found in IndexedDB`);
#endif
        {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.readyState, 4, 'i16') }}} // Mimic XHR readyState 4 === 'DONE: The operation is complete'
        {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.status, 404, 'i16') }}} // Mimic XHR HTTP status code 404 "Not Found"
        stringToUTF8("Not Found", fetch + {{{ C_STRUCTS.emscripten_fetch_t.statusText }}}, 64);
        onerror(fetch, 0, 'no data');
      }
    };
    getRequest.onerror = (error) => {
#if FETCH_DEBUG
      dbg(`fetch: Failed to load file ${pathStr} from IndexedDB!`);
#endif
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.readyState, 4, 'i16') }}} // Mimic XHR readyState 4 === 'DONE: The operation is complete'
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.status, 404, 'i16') }}} // Mimic XHR HTTP status code 404 "Not Found"
      stringToUTF8("Not Found", fetch + {{{ C_STRUCTS.emscripten_fetch_t.statusText }}}, 64);
      onerror(fetch, 0, error);
    };
  } catch(e) {
#if FETCH_DEBUG
    dbg(`fetch: Failed to load file ${pathStr} from IndexedDB! Got exception ${e}`);
#endif
    onerror(fetch, 0, e);
  }
}

function fetchCacheData(/** @type {IDBDatabase} */ db, fetch, data, onsuccess, onerror) {
  if (!db) {
#if FETCH_DEBUG
    dbg('fetch: IndexedDB not available!');
#endif
    onerror(fetch, 0, 'IndexedDB not available!');
    return;
  }

  var fetch_attr = fetch + {{{ C_STRUCTS.emscripten_fetch_t.__attributes }}};
  var destinationPath = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.destinationPath, '*') }}};
  destinationPath ||= {{{ makeGetValue('fetch', C_STRUCTS.emscripten_fetch_t.url, '*') }}};
  var destinationPathStr = UTF8ToString(destinationPath);

  try {
    var transaction = db.transaction(['FILES'], 'readwrite');
    var packages = transaction.objectStore('FILES');
    var putRequest = packages.put(data, destinationPathStr);
    putRequest.onsuccess = (event) => {
#if FETCH_DEBUG
      dbg(`fetch: Stored file "${destinationPathStr}" to IndexedDB cache.`);
#endif
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.readyState, 4, 'i16') }}} // Mimic XHR readyState 4 === 'DONE: The operation is complete'
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.status, 200, 'i16') }}} // Mimic XHR HTTP status code 200 "OK"
      stringToUTF8("OK", fetch + {{{ C_STRUCTS.emscripten_fetch_t.statusText }}}, 64);
      onsuccess(fetch, 0, destinationPathStr);
    };
    putRequest.onerror = (error) => {
#if FETCH_DEBUG
      dbg(`fetch: Failed to store file "${destinationPathStr}" to IndexedDB cache!`);
#endif
      // Most likely we got an error if IndexedDB is unwilling to store any more data for this page.
      // TODO: Can we identify and break down different IndexedDB-provided errors and convert those
      // to more HTTP status codes for more information?
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.readyState, 4, 'i16') }}} // Mimic XHR readyState 4 === 'DONE: The operation is complete'
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.status, 413, 'i16') }}} // Mimic XHR HTTP status code 413 "Payload Too Large"
      stringToUTF8("Payload Too Large", fetch + {{{ C_STRUCTS.emscripten_fetch_t.statusText }}}, 64);
      onerror(fetch, 0, error);
    };
  } catch(e) {
#if FETCH_DEBUG
      dbg(`fetch: Failed to store file "${destinationPathStr}" to IndexedDB cache! Exception: ${e}`);
#endif
    onerror(fetch, 0, e);
  }
}
#endif // ~FETCH_SUPPORT_INDEXEDDB

function fetchXHR(fetch, onsuccess, onerror, onprogress, onreadystatechange) {
  var url = {{{ makeGetValue('fetch', C_STRUCTS.emscripten_fetch_t.url, '*') }}};
  if (!url) {
#if FETCH_DEBUG
    dbg('fetch: XHR failed, no URL specified!');
#endif
    onerror(fetch, 'no url specified!');
    return;
  }
  var url_ = UTF8ToString(url);

  var fetch_attr = fetch + {{{ C_STRUCTS.emscripten_fetch_t.__attributes }}};
  var requestMethod = UTF8ToString(fetch_attr + {{{ C_STRUCTS.emscripten_fetch_attr_t.requestMethod }}});
  requestMethod ||= 'GET';
  var timeoutMsecs = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.timeoutMSecs, 'u32') }}};
  var userName = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.userName, '*') }}};
  var password = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.password, '*') }}};
  var requestHeaders = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.requestHeaders, '*') }}};
  var overriddenMimeType = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.overriddenMimeType, '*') }}};
  var dataPtr = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.requestData, '*') }}};
  var dataLength = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.requestDataSize, '*') }}};

  var fetchAttributes = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.attributes, 'u32') }}};
  var fetchAttrLoadToMemory = !!(fetchAttributes & {{{ cDefs.EMSCRIPTEN_FETCH_LOAD_TO_MEMORY }}});
  var fetchAttrStreamData = !!(fetchAttributes & {{{ cDefs.EMSCRIPTEN_FETCH_STREAM_DATA }}});
  var fetchAttrSynchronous = !!(fetchAttributes & {{{ cDefs.EMSCRIPTEN_FETCH_SYNCHRONOUS }}});

  var userNameStr = userName ? UTF8ToString(userName) : undefined;
  var passwordStr = password ? UTF8ToString(password) : undefined;

#if FETCH_STREAMING == 1
  if (fetchAttrStreamData) {
    var xhr = new FetchXHR();
  } else {
    var xhr = new XMLHttpRequest();
  }
#elif FETCH_STREAMING == 2
  // This setting forces using FetchXHR for all requests. Used only in testing.
  var xhr = new FetchXHR();
#else
  var xhr = new XMLHttpRequest();
#endif
  xhr.withCredentials = !!{{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.withCredentials, 'u8') }}};;
  xhr._streamData = fetchAttrStreamData;
#if FETCH_DEBUG
  dbg(`fetch: xhr.timeout: ${xhr.timeout}, xhr.withCredentials: ${xhr.withCredentials}`);
  dbg(`fetch: xhr.open(requestMethod="${requestMethod}", url: "${url}", userName: ${userNameStr}, password: ${passwordStr}`);
#endif
  xhr.open(requestMethod, url_, !fetchAttrSynchronous, userNameStr, passwordStr);
  if (!fetchAttrSynchronous) xhr.timeout = timeoutMsecs; // XHR timeout field is only accessible in async XHRs, and must be set after .open() but before .send().
  xhr.url_ = url_; // Save the url for debugging purposes (and for comparing to the responseURL that server side advertised)
#if ASSERTIONS && !FETCH_STREAMING
  assert(!fetchAttrStreamData, 'streaming is only supported when FETCH_STREAMING is enabled');
#endif
  xhr.responseType = 'arraybuffer';

  if (overriddenMimeType) {
    var overriddenMimeTypeStr = UTF8ToString(overriddenMimeType);
#if FETCH_DEBUG
    dbg(`fetch: xhr.overrideMimeType("${overriddenMimeTypeStr}");`);
#endif
    xhr.overrideMimeType(overriddenMimeTypeStr);
  }
  if (requestHeaders) {
    for (;;) {
      var key = {{{ makeGetValue('requestHeaders', 0, '*') }}};
      if (!key) break;
      var value = {{{ makeGetValue('requestHeaders', POINTER_SIZE, '*') }}};
      if (!value) break;
      requestHeaders += {{{ 2 * POINTER_SIZE }}};
      var keyStr = UTF8ToString(key);
      var valueStr = UTF8ToString(value);
#if FETCH_DEBUG
      dbg(`fetch: xhr.setRequestHeader("${keyStr}", "${valueStr}");`);
#endif
      xhr.setRequestHeader(keyStr, valueStr);
    }
  }

  var id = Fetch.xhrs.allocate(xhr);
#if FETCH_DEBUG
  dbg(`fetch: id=${id}`);
#endif
  {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.id, 'id', 'u32') }}};
  var data = (dataPtr && dataLength) ? {{{ getHeapViewOrCopy('HEAPU8', 'dataPtr', 'dataPtr + dataLength') }}} : null;
  // TODO: Support specifying custom headers to the request.

  // Share the code to save the response, as we need to do so both on success
  // and on error (despite an error, there may be a response, like a 404 page).
  // This receives a condition, which determines whether to save the xhr's
  // response, or just 0.
  function saveResponseAndStatus() {
    var ptr = 0;
    var ptrLen = 0;
    if (xhr.response && fetchAttrLoadToMemory && {{{ makeGetValue('fetch', C_STRUCTS.emscripten_fetch_t.data, '*') }}} === 0) {
      ptrLen = xhr.response.byteLength;
    }
    if (ptrLen > 0) {
#if FETCH_DEBUG
      dbg(`fetch: allocating ${ptrLen} bytes in Emscripten heap for xhr data`);
#endif
      // The data pointer malloc()ed here has the same lifetime as the emscripten_fetch_t structure itself has, and is
      // freed when emscripten_fetch_close() is called.
      ptr = _realloc({{{ makeGetValue('fetch', C_STRUCTS.emscripten_fetch_t.data, '*') }}}, ptrLen);
      HEAPU8.set(new Uint8Array(/** @type{Array<number>} */(xhr.response)), ptr);
    }
    {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.data, 'ptr', '*') }}}
    writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.numBytes }}}, ptrLen);
    writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.dataOffset }}}, 0);
    var len = xhr.response?.byteLength ?? 0;
    if (len) {
      // If the final XHR.onload handler receives the bytedata to compute total length, report that,
      // otherwise don't write anything out here, which will retain the latest byte size reported in
      // the most recent XHR.onprogress handler.
      writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.totalBytes }}}, len);
    }
    {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.readyState, 'xhr.readyState', 'i16') }}}
    {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.status, 'xhr.status', 'i16') }}}
    if (xhr.statusText) stringToUTF8(xhr.statusText, fetch + {{{ C_STRUCTS.emscripten_fetch_t.statusText }}}, 64);
    if (fetchAttrSynchronous) {
      // The response url pointer malloc()ed here has the same lifetime as the emscripten_fetch_t structure itself has, and is
      // freed when emscripten_fetch_close() is called.
      var ruPtr = stringToNewUTF8(xhr.responseURL);
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.responseUrl, 'ruPtr', '*') }}}
    }
  }

  xhr.onload = (e) => {
    // check if xhr was aborted by user and don't try to call back
    if (!Fetch.xhrs.has(id)) {
      return;
    }
    saveResponseAndStatus();
    if (xhr.status >= 200 && xhr.status < 300) {
#if FETCH_DEBUG
      dbg(`fetch: xhr of URL "${xhr.url_}" / responseURL "${xhr.responseURL}" succeeded with status ${xhr.status}`);
#endif
#if ASSERTIONS
      if (fetchAttrStreamData) {
        assert(xhr.response === null);
      }
#endif
      onsuccess(fetch, xhr, e);
    } else {
#if FETCH_DEBUG
      dbg(`fetch: xhr of URL "${xhr.url_}" / responseURL "${xhr.responseURL}" failed with status ${xhr.status}`);
#endif
      onerror(fetch, e);
    }
  };
  xhr.onerror = (e) => {
    // check if xhr was aborted by user and don't try to call back
    if (!Fetch.xhrs.has(id)) {
      return;
    }
#if FETCH_DEBUG
    dbg(`fetch: xhr of URL "${xhr.url_}" / responseURL "${xhr.responseURL}" finished with error, readyState ${xhr.readyState} and status ${xhr.status}`);
#endif
    saveResponseAndStatus();
    onerror(fetch, e);
  };
  xhr.ontimeout = (e) => {
    // check if xhr was aborted by user and don't try to call back
    if (!Fetch.xhrs.has(id)) {
      return;
    }
#if FETCH_DEBUG
    dbg(`fetch: xhr of URL "${xhr.url_}" / responseURL "${xhr.responseURL}" timed out, readyState ${xhr.readyState} and status ${xhr.status}`);
#endif
    onerror(fetch, e);
  };
  xhr.onprogress = (e) => {
    // check if xhr was aborted by user and don't try to call back
    if (!Fetch.xhrs.has(id)) {
      return;
    }
    var ptrLen = (fetchAttrLoadToMemory && fetchAttrStreamData) ? xhr.response?.byteLength ?? 0 : 0;

    // Specifies the maximum chunk size that a streaming fetch will transfer from
    // JS over to WebAssembly side. Used to cap a streaming fetch to avoid
    // overallocating WebAssembly memory needlessly.
    var FETCH_STREAMING_MAX_CHUNK_SIZE = 8*1024*1024;

    for (var bytePos = 0; bytePos < ptrLen || !ptrLen;) {
      var sz = Math.min(ptrLen - bytePos, FETCH_STREAMING_MAX_CHUNK_SIZE);

      var ptr = 0;
      if (sz > 0 && fetchAttrLoadToMemory && fetchAttrStreamData) {
        // Even though we are doing a streaming fetch (i.e. in small chunks), Safari may call onprogress with a huge
        // chunk size. This will be a problem for Wasm applications that intend to use streaming fetch to process
        // an input file in small chunks (to avoid blowing up the WebAssembly heap size). Therefore apply a max
        // chunk size ceiling to the received chunks, and transfer the data over to WebAssembly using max sized chunks.

#if FETCH_DEBUG
        dbg(`fetch: allocating ${sz} bytes in Emscripten heap for xhr data`);
#endif
#if ASSERTIONS
        assert(onprogress, 'streaming fetch requires an onprogress handler');
#endif
        // The data pointer malloc()ed here has the same lifetime as the emscripten_fetch_t structure itself has, and is
        // freed when emscripten_fetch_close() is called.
        ptr = _realloc({{{ makeGetValue('fetch', C_STRUCTS.emscripten_fetch_t.data, '*') }}}, sz);
        HEAPU8.set(new Uint8Array(/** @type{Array<number>} */(xhr.response), bytePos, sz), ptr);
      }
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.data, 'ptr', '*') }}}
      writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.numBytes }}}, sz);
      writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.dataOffset }}}, e.loaded - ptrLen + bytePos);
      writeI53ToI64(fetch + {{{ C_STRUCTS.emscripten_fetch_t.totalBytes }}}, e.total);
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.readyState, 'xhr.readyState', 'i16') }}}
      var status = xhr.status;
      // If loading files from a source that does not give HTTP status code, assume success if we get data bytes
      if (xhr.readyState >= 3 && xhr.status === 0 && e.loaded > 0) status = 200;
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.status, 'status', 'i16') }}}
      if (xhr.statusText) stringToUTF8(xhr.statusText, fetch + {{{ C_STRUCTS.emscripten_fetch_t.statusText }}}, 64);
      onprogress(fetch, e);
      bytePos += sz;
      if (!ptrLen) break;
    }
  };
  xhr.onreadystatechange = (e) => {
    // check if xhr was aborted by user and don't try to call back
    if (!Fetch.xhrs.has(id)) {
      {{{ runtimeKeepalivePop() }}}
      return;
    }
    {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.readyState, 'xhr.readyState', 'i16') }}}
    if (xhr.readyState >= 2) {
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.status, 'xhr.status', 'i16') }}}
    }
    if (!fetchAttrSynchronous && (xhr.readyState === 2 && xhr.responseURL.length > 0)) {
      // The response url pointer malloc()ed here has the same lifetime as the emscripten_fetch_t structure itself has, and is
      // freed when emscripten_fetch_close() is called.
      var ruPtr = stringToNewUTF8(xhr.responseURL);
      {{{ makeSetValue('fetch', C_STRUCTS.emscripten_fetch_t.responseUrl, 'ruPtr', '*') }}}
    }
    onreadystatechange(fetch, e);
  };
#if FETCH_DEBUG
  dbg(`fetch: xhr.send(data=${data})`);
#endif
  try {
    xhr.send(data);
  } catch(e) {
#if FETCH_DEBUG
    dbg(`fetch: xhr failed with exception: ${e}`);
#endif
    onerror(fetch, e);
  }
}

function startFetch(fetch, successcb, errorcb, progresscb, readystatechangecb) {
  // Avoid shutting down the runtime since we want to wait for the async
  // response.
  {{{ runtimeKeepalivePush() }}}

  var fetch_attr = fetch + {{{ C_STRUCTS.emscripten_fetch_t.__attributes }}};
  var onsuccess = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.onsuccess, '*') }}};
  var onerror = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.onerror, '*') }}};
  var onprogress = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.onprogress, '*') }}};
  var onreadystatechange = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.onreadystatechange, '*') }}};
  var fetchAttributes = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.attributes, '*') }}};
  var fetchAttrSynchronous = !!(fetchAttributes & {{{ cDefs.EMSCRIPTEN_FETCH_SYNCHRONOUS }}});

  function doCallback(f) {
    if (fetchAttrSynchronous) {
      f();
    } else {
      callUserCallback(f);
    }
  }

  var reportSuccess = (fetch, xhr, e) => {
#if FETCH_DEBUG
    dbg(`fetch: operation success. e: ${e}`);
#endif
    {{{ runtimeKeepalivePop() }}}
    doCallback(() => {
      if (onsuccess) {{{ makeDynCall('vp', 'onsuccess') }}}(fetch);
      else successcb?.(fetch);
    });
  };

  var reportProgress = (fetch, e) => {
    doCallback(() => {
      if (onprogress) {{{ makeDynCall('vp', 'onprogress') }}}(fetch);
      else progresscb?.(fetch);
    });
  };

  var reportError = (fetch, e) => {
#if FETCH_DEBUG
    dbg(`fetch: operation failed: ${e}`);
#endif
    {{{ runtimeKeepalivePop() }}}
    doCallback(() => {
      if (onerror) {{{ makeDynCall('vp', 'onerror') }}}(fetch);
      else errorcb?.(fetch);
    });
  };

  var reportReadyStateChange = (fetch, e) => {
#if FETCH_DEBUG
    dbg(`fetch: ready state change. e: ${e}`);
#endif
    doCallback(() => {
      if (onreadystatechange) {{{ makeDynCall('vp', 'onreadystatechange') }}}(fetch);
      else readystatechangecb?.(fetch);
    });
  };

  var performUncachedXhr = (fetch, xhr, e) => {
#if FETCH_DEBUG
    dbg(`fetch: starting (uncached) XHR: ${e}`);
#endif
    fetchXHR(fetch, reportSuccess, reportError, reportProgress, reportReadyStateChange);
  };

#if FETCH_SUPPORT_INDEXEDDB
  var cacheResultAndReportSuccess = (fetch, xhr, e) => {
#if FETCH_DEBUG
    dbg(`fetch: operation success. Caching result.. e: ${e}`);
#endif
    var storeSuccess = (fetch, xhr, e) => {
#if FETCH_DEBUG
      dbg('fetch: IndexedDB store succeeded.');
#endif
      {{{ runtimeKeepalivePop() }}}
      doCallback(() => {
        if (onsuccess) {{{ makeDynCall('vp', 'onsuccess') }}}(fetch);
        else successcb?.(fetch);
      });
    };
    var storeError = (fetch, xhr, e) => {
#if FETCH_DEBUG
      dbg('fetch: IndexedDB store failed.');
#endif
      {{{ runtimeKeepalivePop() }}}
      doCallback(() => {
        if (onsuccess) {{{ makeDynCall('vp', 'onsuccess') }}}(fetch);
        else successcb?.(fetch);
      });
    };
    fetchCacheData(Fetch.dbInstance, fetch, xhr.response, storeSuccess, storeError);
  };

  var performCachedXhr = (fetch, xhr, e) => {
#if FETCH_DEBUG
    dbg(`fetch: starting (cached) XHR: ${e}`);
#endif
    fetchXHR(fetch, cacheResultAndReportSuccess, reportError, reportProgress, reportReadyStateChange);
  };

  var requestMethod = UTF8ToString(fetch_attr + {{{ C_STRUCTS.emscripten_fetch_attr_t.requestMethod }}});
  var fetchAttrReplace = !!(fetchAttributes & {{{ cDefs.EMSCRIPTEN_FETCH_REPLACE }}});
  var fetchAttrPersistFile = !!(fetchAttributes & {{{ cDefs.EMSCRIPTEN_FETCH_PERSIST_FILE }}});
  var fetchAttrNoDownload = !!(fetchAttributes & {{{ cDefs.EMSCRIPTEN_FETCH_NO_DOWNLOAD }}});
  if (requestMethod === 'EM_IDB_STORE') {
    var ptr = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.requestData, '*') }}};
    var size = {{{ makeGetValue('fetch_attr', C_STRUCTS.emscripten_fetch_attr_t.requestDataSize, '*') }}};
    // Storing shared or resizable typed arrays to IndexedDB is not allowed, so use getHeapViewOrCopy.
    fetchCacheData(Fetch.dbInstance, fetch, {{{ getHeapViewOrCopy('HEAPU8', 'ptr', 'ptr + size') }}}, reportSuccess, reportError);
  } else if (requestMethod === 'EM_IDB_DELETE') {
    fetchDeleteCachedData(Fetch.dbInstance, fetch, reportSuccess, reportError);
  } else if (!fetchAttrReplace) {
    fetchLoadCachedData(Fetch.dbInstance, fetch, reportSuccess, fetchAttrNoDownload ? reportError : (fetchAttrPersistFile ? performCachedXhr : performUncachedXhr));
  } else if (!fetchAttrNoDownload) {
    fetchXHR(fetch, fetchAttrPersistFile ? cacheResultAndReportSuccess : reportSuccess, reportError, reportProgress, reportReadyStateChange);
  } else {
#if FETCH_DEBUG
    dbg('fetch: Invalid combination of flags passed.');
#endif
    return 0; // todo: free
  }
  return fetch;
#else // !FETCH_SUPPORT_INDEXEDDB
  fetchXHR(fetch, reportSuccess, reportError, reportProgress, reportReadyStateChange);
  return fetch;
#endif // ~FETCH_SUPPORT_INDEXEDDB
}

function fetchGetResponseHeadersLength(id) {
  return lengthBytesUTF8(Fetch.xhrs.get(id).getAllResponseHeaders());
}

function fetchGetResponseHeaders(id, dst, dstSizeBytes) {
  var responseHeaders = Fetch.xhrs.get(id).getAllResponseHeaders();
  return stringToUTF8(responseHeaders, dst, dstSizeBytes) + 1;
}

// Delete the xhr JS object, allowing it to be garbage collected.
function fetchFree(id) {
#if FETCH_DEBUG
  dbg(`fetch: fetchFree id:${id}`);
#endif
  if (Fetch.xhrs.has(id)) {
    var xhr = Fetch.xhrs.get(id);
    Fetch.xhrs.free(id);
    // check if fetch is still in progress and should be aborted
    if (xhr.readyState > 0 && xhr.readyState < 4) {
      xhr.abort();
    }
  }
}
