#preprocess

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

var emscriptenThreadProfiler = {
  // UI update interval in milliseconds.
  uiUpdateIntervalMsecs: 1000,

  // UI div element.
  threadProfilerDiv: null,

  // Installs startup hook and periodic UI update timer.
  initialize() {
    var self = emscriptenThreadProfiler;
    self.threadProfilerDiv = document.getElementById('threadprofiler');
    if (!self.threadProfilerDiv) {
      var div = document.createElement("div");
      div.innerHTML = "<div id='threadprofiler' style='margin: 20px; border: solid 1px black;'></div>";
      document.body.appendChild(div);
      self.threadProfilerDiv = document.getElementById('threadprofiler');
    }
    var i = setInterval(() => self.updateUi(), self.uiUpdateIntervalMsecs);
    addOnExit(() => clearInterval(i));
  },

  initializeNode() {
    addOnInit(() => {
      var self = emscriptenThreadProfiler;
      self.dumpState();
      var i = setInterval(() => self.dumpState(), self.uiUpdateIntervalMsecs);
      addOnExit(() => clearInterval(i));
    });
  },

  dumpState() {
    var mainThread = _emscripten_main_runtime_thread_id();

    var threads = [mainThread];
    for (var thread of Object.values(PThread.pthreads)) {
      threads.push(thread.pthread_ptr);
    }
    for (var threadPtr of threads) {
      var threadName = PThread.getThreadName(threadPtr);
      if (threadName) {
        threadName = `"${threadName}" (${ptrToString(threadPtr)})`;
      } else {
        threadName = `(${ptrToString(threadPtr)})`;
      }

      console.log(`Thread ${threadName} now: ${PThread.threadStatusAsString(threadPtr)}. `);
    }
  },

  updateUi() {
    if (typeof PThread == 'undefined') {
      // Likely running threadprofiler on a singlethreaded build, or not
      // initialized yet, ignore updating.
      return;
    }
    if (!runtimeInitialized) {
      return;
    }
    var str = '';
    var mainThread = _emscripten_main_runtime_thread_id();

    var threads = [mainThread];
    for (var thread of Object.values(PThread.pthreads)) {
      threads.push(thread.pthread_ptr);
    }

    for (var threadPtr of threads) {
      var profilerBlock = Atomics.load({{{ getHeapForType('*') }}}, {{{ getHeapOffset('threadPtr + ' + C_STRUCTS.pthread.profilerBlock, '*') }}});
#if MEMORY64
      profilerBlock = Number(profilerBlock);
#endif
      var threadName = PThread.getThreadName(threadPtr);
      if (threadName) {
        threadName = `"${threadName}" (${ptrToString(threadPtr)})`;
      } else {
        threadName = `(${ptrToString(threadPtr)})`;
      }

      str += `Thread ${threadName} now: ${PThread.threadStatusAsString(threadPtr)}. `;

      var threadTimesInStatus = [];
      var totalTime = 0;
      var offset = profilerBlock + {{{ C_STRUCTS.thread_profiler_block.timeSpentInStatus }}};
      for (var j = 0; j < {{{ cDefs.EM_THREAD_STATUS_NUMFIELDS }}}; ++j, offset += 8) {
        threadTimesInStatus.push({{{ makeGetValue('offset', 0, 'double') }}});
        totalTime += threadTimesInStatus[j];
        {{{ makeSetValue('offset', 0, 0, 'double') }}};
      }
      var recent = '';
      if (threadTimesInStatus[1] > 0) recent += (threadTimesInStatus[1] / totalTime * 100.0).toFixed(1) + '% running. ';
      if (threadTimesInStatus[2] > 0) recent += (threadTimesInStatus[2] / totalTime * 100.0).toFixed(1) + '% sleeping. ';
      if (threadTimesInStatus[3] > 0) recent += (threadTimesInStatus[3] / totalTime * 100.0).toFixed(1) + '% waiting for futex. ';
      if (threadTimesInStatus[4] > 0) recent += (threadTimesInStatus[4] / totalTime * 100.0).toFixed(1) + '% waiting for mutex. ';
      if (threadTimesInStatus[5] > 0) recent += (threadTimesInStatus[5] / totalTime * 100.0).toFixed(1) + '% waiting for proxied ops. ';
      if (recent.length > 0) str += `Recent activity: ${recent}`;
      str += '<br />';
    }
    emscriptenThreadProfiler.threadProfilerDiv.innerHTML = str;
  }
};

if (globalThis.document) {
  emscriptenThreadProfiler.initialize();
} else if (!ENVIRONMENT_IS_PTHREAD && globalThis.process) {
  emscriptenThreadProfiler.initializeNode();
}
