/// <reference lib="webworker" />
import {
  EcmaScriptEngineAdapter,
  executeEcmaScript,
  replaceEcmaScript,
} from "../regex/execution/adapters/ecmascript/EcmaScriptEngineAdapter";
import {
  WORKER_PROTOCOL_VERSION,
  workerError,
  type EngineWorkerOperation,
  type EngineWorkerResult,
  type WorkerRequest,
  type WorkerResponse,
} from "../regex/execution/worker-protocol";

const scope = self as DedicatedWorkerGlobalScope;
const adapter = new EcmaScriptEngineAdapter();

scope.onmessage = async (
  event: MessageEvent<WorkerRequest<EngineWorkerOperation>>,
) => {
  const request = event.data;
  if (request.protocolVersion !== WORKER_PROTOCOL_VERSION) return;
  let response: WorkerResponse<EngineWorkerResult>;
  try {
    const payload: EngineWorkerResult =
      request.payload.kind === "load"
        ? {
            kind: "load",
            info: await adapter.load(),
          }
        : request.payload.kind === "execute"
          ? {
              kind: "execute",
              result: executeEcmaScript(request.payload.request),
            }
          : {
              kind: "replace",
              result: replaceEcmaScript(request.payload.request),
            };
    response = {
      protocolVersion: WORKER_PROTOCOL_VERSION,
      requestId: request.requestId,
      generation: request.generation,
      ok: true,
      payload,
    };
  } catch (error) {
    response = {
      protocolVersion: WORKER_PROTOCOL_VERSION,
      requestId: request.requestId,
      generation: request.generation,
      ok: false,
      error: workerError(error),
    };
  }
  scope.postMessage(response);
};
