"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const platform = require("../common/platform.js");
const simpleWorker = require("../common/worker/simpleWorker.js");
var _a;
const ttPolicy = (_a = window.trustedTypes) === null || _a === void 0 ? void 0 : _a.createPolicy("defaultWorkerFactory", { createScriptURL: (value) => value });
function getWorker(label) {
  if (platform.globals.MonacoEnvironment) {
    if (typeof platform.globals.MonacoEnvironment.getWorker === "function") {
      return platform.globals.MonacoEnvironment.getWorker("workerMain.js", label);
    }
    if (typeof platform.globals.MonacoEnvironment.getWorkerUrl === "function") {
      const workerUrl = platform.globals.MonacoEnvironment.getWorkerUrl("workerMain.js", label);
      return new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) : workerUrl, { name: label });
    }
  }
  throw new Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`);
}
function isPromiseLike(obj) {
  if (typeof obj.then === "function") {
    return true;
  }
  return false;
}
class WebWorker {
  constructor(moduleId, id, label, onMessageCallback, onErrorCallback) {
    this.id = id;
    const workerOrPromise = getWorker(label);
    if (isPromiseLike(workerOrPromise)) {
      this.worker = workerOrPromise;
    } else {
      this.worker = Promise.resolve(workerOrPromise);
    }
    this.postMessage(moduleId, []);
    this.worker.then((w) => {
      w.onmessage = function(ev) {
        onMessageCallback(ev.data);
      };
      w.onmessageerror = onErrorCallback;
      if (typeof w.addEventListener === "function") {
        w.addEventListener("error", onErrorCallback);
      }
    });
  }
  getId() {
    return this.id;
  }
  postMessage(message, transfer) {
    if (this.worker) {
      this.worker.then((w) => w.postMessage(message, transfer));
    }
  }
  dispose() {
    if (this.worker) {
      this.worker.then((w) => w.terminate());
    }
    this.worker = null;
  }
}
class DefaultWorkerFactory {
  constructor(label) {
    this._label = label;
    this._webWorkerFailedBeforeError = false;
  }
  create(moduleId, onMessageCallback, onErrorCallback) {
    let workerId = ++DefaultWorkerFactory.LAST_WORKER_ID;
    if (this._webWorkerFailedBeforeError) {
      throw this._webWorkerFailedBeforeError;
    }
    return new WebWorker(moduleId, workerId, this._label || "anonymous" + workerId, onMessageCallback, (err) => {
      simpleWorker.logOnceWebWorkerWarning(err);
      this._webWorkerFailedBeforeError = err;
      onErrorCallback(err);
    });
  }
}
DefaultWorkerFactory.LAST_WORKER_ID = 0;
exports.DefaultWorkerFactory = DefaultWorkerFactory;
