import type { Pcre2TraceRequest, Pcre2TraceResult } from "../model/trace";
import { WorkerSupervisor } from "./WorkerSupervisor";
import type {
  TraceWorkerOperation,
  TraceWorkerResult,
} from "./worker-protocol";

export class Pcre2TraceSupervisor {
  readonly #supervisor: WorkerSupervisor<
    TraceWorkerOperation,
    TraceWorkerResult
  >;

  constructor() {
    this.#supervisor = new WorkerSupervisor<
      TraceWorkerOperation,
      TraceWorkerResult
    >("PCRE2 automatic-callout trace", () => {
      return new Worker(
        new URL("../../workers/pcre2-trace.worker.ts", import.meta.url),
        {
          type: "module",
          name: "regex-tools-pcre2-trace",
        },
      );
    });
  }

  async trace(
    request: Pcre2TraceRequest,
    timeoutMs: number,
  ): Promise<Pcre2TraceResult> {
    const response = await this.#supervisor.run(
      { kind: "trace", request },
      timeoutMs,
      { supersede: true },
    );
    if (response.kind !== "trace") {
      throw new Error("PCRE2 trace worker returned the wrong response kind.");
    }
    return response.result;
  }

  cancel(): void {
    this.#supervisor.cancel();
  }

  dispose(): void {
    this.#supervisor.dispose();
  }
}
