import type {
  RegexExecutionRequest,
  RegexExecutionResult,
  RegexReplacementRequest,
  RegexReplacementResult,
} from "../model/match";
import type { RegexSyntaxRequest, RegexSyntaxResult } from "../model/syntax";
import {
  AVAILABLE_REGEX_FLAVOURS,
  parseRegexFlags,
  parseRegexOptions,
  resolveRegexFlavourVersion,
} from "../flavours/flavour-registry";
import {
  DEFAULT_REGEX_LIMITS,
  utf8ByteLength,
} from "../execution/request-limits";
import { EngineSupervisor } from "../execution/EngineSupervisor";
import { SyntaxSupervisor } from "../execution/SyntaxSupervisor";
import { WorkerRequestError } from "../execution/WorkerSupervisor";
import type {
  ComparisonFlavour,
  ComparisonSideInput,
} from "../comparison/comparison.types";
import type { RegexTestExpectation } from "../tests/test-case.types";
import {
  compareSemanticResults,
  engineIdentity,
  evaluateCaptureRangeMismatch,
  evaluateUnitTestFailure,
  type PredicateEvaluation,
  type SemanticSideResult,
} from "./oracles";
import {
  MINIMIZER_MAXIMUM_SUBJECT_BYTES,
  MINIMIZER_MAXIMUM_WALL_TIME_MS,
  type CandidateSideObservation,
  type MinimizationCandidateObservation,
  type SubjectMinimizationProgress,
  type SubjectMinimizationRequest,
  type SubjectMinimizationResult,
} from "./minimization.types";
import { containsLoneSurrogate, reduceSubject } from "./subject-transforms";

export interface MinimizerSyntaxRunner {
  parsePattern(
    request: RegexSyntaxRequest,
    timeoutMs?: number,
  ): Promise<RegexSyntaxResult>;
  cancel(): void;
  dispose(): void;
}

export interface MinimizerEngineRunner {
  execute(
    request: RegexExecutionRequest,
    timeoutMs: number,
  ): Promise<RegexExecutionResult>;
  replace(
    request: RegexReplacementRequest,
    timeoutMs: number,
  ): Promise<RegexReplacementResult>;
  cancel(): void;
  dispose(): void;
}

export interface SubjectMinimizerDependencies {
  readonly createSyntaxRunner: (
    flavour: ComparisonFlavour,
  ) => MinimizerSyntaxRunner;
  readonly createEngineRunner: () => MinimizerEngineRunner;
  readonly now: () => number;
}

const DEFAULT_DEPENDENCIES: SubjectMinimizerDependencies = {
  createSyntaxRunner: (flavour) =>
    new SyntaxSupervisor(
      `${flavour} minimizer syntax`,
      `regex-tools-minimizer-${flavour}-syntax`,
    ),
  createEngineRunner: () => new EngineSupervisor(),
  now: () => performance.now(),
};

interface PreparedSide {
  readonly input: ComparisonSideInput;
  readonly syntaxRequest: RegexSyntaxRequest;
  readonly captures: readonly RegexSyntaxResult["captures"][number][];
}

interface SideRuntimeComplete {
  readonly status: "complete";
  readonly execution: RegexExecutionResult;
  readonly replacement?: RegexReplacementResult;
}

interface SideRuntimeFailure {
  readonly status: "timeout" | "cancelled" | "crash" | "worker-error";
  readonly message: string;
}

type SideRuntime = SideRuntimeComplete | SideRuntimeFailure;

interface ValidatedRequest {
  readonly request: SubjectMinimizationRequest;
  readonly sides: readonly ComparisonSideInput[];
  readonly targetIdentity: string;
}

function boundedInteger(
  value: number,
  label: string,
  minimum: number,
  maximum: number,
): number {
  if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {
    throw new RangeError(
      `${label} must be an integer from ${minimum.toLocaleString()} to ${maximum.toLocaleString()}.`,
    );
  }
  return value;
}

function normalizedSide(input: ComparisonSideInput): ComparisonSideInput {
  const definition = AVAILABLE_REGEX_FLAVOURS.require(input.flavour);
  const version = resolveRegexFlavourVersion(
    input.flavourVersion,
    definition,
    `${definition.label} minimizer version`,
  ).definition;
  const flags = parseRegexFlags(
    input.flags,
    definition,
    `${definition.label} minimizer flags`,
  );
  const options = parseRegexOptions(
    input.options,
    definition,
    `${definition.label} minimizer options`,
  );
  if (input.pattern.length > DEFAULT_REGEX_LIMITS.patternHardLengthUtf16) {
    throw new RangeError(
      `${definition.label} minimizer pattern exceeds the ${DEFAULT_REGEX_LIMITS.patternHardLengthUtf16.toLocaleString()} UTF-16 unit limit.`,
    );
  }
  if (
    input.replacement !== undefined &&
    input.replacement.length >
      DEFAULT_REGEX_LIMITS.maximumReplacementTemplateUtf16
  ) {
    throw new RangeError(
      `${definition.label} replacement exceeds the ${DEFAULT_REGEX_LIMITS.maximumReplacementTemplateUtf16.toLocaleString()} UTF-16 unit limit.`,
    );
  }
  return {
    flavour: input.flavour,
    flavourVersion: version.value,
    pattern: input.pattern,
    flags,
    options,
    ...(input.replacement === undefined
      ? {}
      : { replacement: input.replacement }),
  };
}

function stableValue(value: unknown): unknown {
  if (Array.isArray(value)) return value.map(stableValue);
  if (value && typeof value === "object") {
    return Object.fromEntries(
      Object.entries(value)
        .sort(([left], [right]) => left.localeCompare(right))
        .map(([key, entry]) => [key, stableValue(entry)]),
    );
  }
  return value;
}

function identity(value: unknown): string {
  const source = JSON.stringify(stableValue(value));
  let hash = 0x811c9dc5;
  for (let index = 0; index < source.length; index += 1) {
    hash ^= source.charCodeAt(index);
    hash = Math.imul(hash, 0x01000193);
  }
  return `minimization-${(hash >>> 0).toString(16).padStart(8, "0")}`;
}

function validateCaptureSelector(
  value: {
    readonly matchIndex: number;
    readonly groupNumber?: number;
    readonly groupName?: string;
  },
  label: string,
): void {
  boundedInteger(value.matchIndex, `${label} match index`, 0, 1_000_000);
  if (value.groupNumber === undefined && value.groupName === undefined) {
    throw new Error(`${label} requires a capture number or name.`);
  }
  if (value.groupNumber !== undefined) {
    boundedInteger(
      value.groupNumber,
      `${label} group number`,
      1,
      DEFAULT_REGEX_LIMITS.maximumCaptureGroups,
    );
  }
  if (
    value.groupName !== undefined &&
    (value.groupName.length === 0 || value.groupName.length > 256)
  ) {
    throw new Error(`${label} group name must contain 1–256 UTF-16 units.`);
  }
}

function validateExpectation(expectation: RegexTestExpectation): void {
  switch (expectation.kind) {
    case "match-count":
      boundedInteger(
        expectation.count,
        "Expected match count",
        0,
        DEFAULT_REGEX_LIMITS.maximumMatches,
      );
      return;
    case "full-match":
      boundedInteger(
        expectation.matchIndex,
        "Expected match index",
        0,
        DEFAULT_REGEX_LIMITS.maximumMatches - 1,
      );
      return;
    case "capture":
      validateCaptureSelector(expectation, "Capture expectation");
      return;
    case "must-complete-within":
      boundedInteger(
        expectation.milliseconds,
        "Completion assertion",
        1,
        DEFAULT_REGEX_LIMITS.advancedMaximumTimeoutMs,
      );
      return;
    default:
      return;
  }
}

export function validateSubjectMinimizationRequest(
  input: SubjectMinimizationRequest,
): ValidatedRequest {
  if (input.schemaVersion !== 1) {
    throw new Error("Unsupported subject-minimization request schema.");
  }
  if (containsLoneSurrogate(input.subject)) {
    throw new Error(
      "Subject minimization requires well-formed Unicode and rejects lone surrogate code units.",
    );
  }
  if (utf8ByteLength(input.subject) > MINIMIZER_MAXIMUM_SUBJECT_BYTES) {
    throw new RangeError(
      `Subject minimization is limited to ${MINIMIZER_MAXIMUM_SUBJECT_BYTES.toLocaleString()} UTF-8 bytes.`,
    );
  }
  const maximumEvaluations = boundedInteger(
    input.budgets.maximumEvaluations,
    "Minimizer evaluation budget",
    1,
    DEFAULT_REGEX_LIMITS.maximumMinimizerRuns,
  );
  const maximumWallTimeMs = boundedInteger(
    input.budgets.maximumWallTimeMs,
    "Minimizer wall-time budget",
    1,
    MINIMIZER_MAXIMUM_WALL_TIME_MS,
  );
  const candidateTimeoutMs = boundedInteger(
    input.budgets.candidateTimeoutMs,
    "Minimizer candidate timeout",
    1,
    DEFAULT_REGEX_LIMITS.advancedMaximumTimeoutMs,
  );
  if (candidateTimeoutMs > maximumWallTimeMs) {
    throw new RangeError(
      "The fixed candidate timeout must fit inside the aggregate wall-time budget.",
    );
  }
  const maximumMatches = boundedInteger(
    input.maximumMatches,
    "Minimizer match limit",
    1,
    DEFAULT_REGEX_LIMITS.maximumMatches,
  );
  const maximumCaptureRows = boundedInteger(
    input.maximumCaptureRows,
    "Minimizer capture-row limit",
    1,
    DEFAULT_REGEX_LIMITS.maximumCaptureRows,
  );
  const maximumOutputBytes = boundedInteger(
    input.maximumOutputBytes,
    "Minimizer replacement-output limit",
    1,
    DEFAULT_REGEX_LIMITS.maximumReplacementOutputBytes,
  );

  let sides: readonly ComparisonSideInput[];
  let target: SubjectMinimizationRequest["target"];
  if (input.target.kind === "engine") {
    const side = normalizedSide(input.target.side);
    if (input.target.oracle.kind === "unit-test-failure") {
      validateExpectation(input.target.oracle.expectation);
      if (
        input.target.oracle.expectation.kind === "replacement" &&
        side.replacement === undefined
      ) {
        throw new Error(
          "A replacement unit-test failure requires an explicit replacement template.",
        );
      }
    } else if (input.target.oracle.kind === "capture-range-mismatch") {
      validateCaptureSelector(input.target.oracle, "Capture-range mismatch");
      const range = input.target.oracle.expectedRange;
      if (
        !Number.isSafeInteger(range.startUtf16) ||
        !Number.isSafeInteger(range.endUtf16) ||
        range.startUtf16 < 0 ||
        range.endUtf16 < range.startUtf16 ||
        range.endUtf16 > input.subject.length
      ) {
        throw new RangeError(
          "Expected capture range must be a valid UTF-16 interval in the original subject.",
        );
      }
    }
    target = { ...input.target, side };
    sides = [side];
  } else {
    const normalized = input.target.sides.map(normalizedSide);
    const ecmascript = normalized.find((side) => side.flavour === "ecmascript");
    const pcre2 = normalized.find((side) => side.flavour === "pcre2");
    if (
      normalized.length !== 2 ||
      !ecmascript ||
      !pcre2 ||
      ecmascript === pcre2
    ) {
      throw new Error(
        "Comparison minimization requires exactly one ECMAScript side and one PCRE2 side.",
      );
    }
    if (
      input.target.operation === "replace" &&
      normalized.some((side) => side.replacement === undefined)
    ) {
      throw new Error(
        "Replacement comparison minimization requires both replacement templates.",
      );
    }
    const pair = [ecmascript, pcre2] as const;
    target = { ...input.target, sides: pair };
    sides = pair;
  }
  const request: SubjectMinimizationRequest = {
    schemaVersion: 1,
    subject: input.subject,
    target,
    budgets: {
      maximumEvaluations,
      maximumWallTimeMs,
      candidateTimeoutMs,
    },
    maximumMatches,
    maximumCaptureRows,
    maximumOutputBytes,
  };
  return {
    request,
    sides,
    targetIdentity: identity({
      target,
      maximumMatches,
      maximumCaptureRows,
      maximumOutputBytes,
      candidateTimeoutMs,
    }),
  };
}

function classifyWorkerFailure(error: unknown): SideRuntimeFailure {
  const kind =
    error instanceof WorkerRequestError
      ? error.kind
      : error &&
          typeof error === "object" &&
          "kind" in error &&
          ["timeout", "cancelled", "crash", "worker-error"].includes(
            String((error as { readonly kind?: unknown }).kind),
          )
        ? (String(
            (error as { readonly kind?: unknown }).kind,
          ) as SideRuntimeFailure["status"])
        : "worker-error";
  return {
    status: kind,
    message: error instanceof Error ? error.message : String(error),
  };
}

function sideObservation(
  flavour: ComparisonFlavour,
  runtime: SideRuntime,
): CandidateSideObservation {
  return {
    flavour,
    status: runtime.status,
    ...(runtime.status === "complete"
      ? { engineIdentity: engineIdentity(runtime.execution) }
      : {}),
  };
}

function sameFingerprint(
  left: readonly string[] | undefined,
  right: readonly string[],
): boolean {
  return (
    left !== undefined &&
    left.length === right.length &&
    left.every((value, index) => value === right[index])
  );
}

function fatalObservation(
  runtime: SideRuntimeFailure,
  sides: readonly CandidateSideObservation[],
): MinimizationCandidateObservation {
  return {
    status: runtime.status,
    reproduced: false,
    fingerprint: [`worker:${runtime.status}`],
    summary:
      runtime.status === "crash"
        ? `A worker crashed. Crash minimization is unsupported and was not treated as a timeout: ${runtime.message}`
        : runtime.message,
    sides,
  };
}

function predicateObservation(
  evaluation: PredicateEvaluation,
  reproduced: boolean,
  side: CandidateSideObservation,
): MinimizationCandidateObservation {
  return {
    status: evaluation.kind === "inconclusive" ? "inconclusive" : "complete",
    reproduced,
    fingerprint: evaluation.fingerprint,
    summary: evaluation.summary,
    sides: [side],
  };
}

export class SubjectMinimizer {
  readonly #dependencies: SubjectMinimizerDependencies;
  readonly #syntax: ReadonlyMap<ComparisonFlavour, MinimizerSyntaxRunner>;
  readonly #engine: MinimizerEngineRunner;
  #generation = 0;
  #disposed = false;

  constructor(
    dependencies: SubjectMinimizerDependencies = DEFAULT_DEPENDENCIES,
  ) {
    this.#dependencies = dependencies;
    this.#syntax = new Map(
      (["ecmascript", "pcre2"] as const).map((flavour) => [
        flavour,
        dependencies.createSyntaxRunner(flavour),
      ]),
    );
    this.#engine = dependencies.createEngineRunner();
  }

  async minimize(
    input: SubjectMinimizationRequest,
    onProgress?: (progress: SubjectMinimizationProgress) => void,
  ): Promise<SubjectMinimizationResult> {
    if (this.#disposed) {
      throw new Error("Subject minimizer has been disposed.");
    }
    this.cancel();
    const generation = this.#generation;
    const startedAtMs = this.#dependencies.now();
    const validated = validateSubjectMinimizationRequest(input);
    onProgress?.({
      phase: "syntax-setup",
      evaluations: 0,
      maximumEvaluations: validated.request.budgets.maximumEvaluations,
      acceptedReductions: 0,
      currentScalars: Array.from(validated.request.subject).length,
      currentUtf8Bytes: utf8ByteLength(validated.request.subject),
      elapsedMs: Math.max(0, this.#dependencies.now() - startedAtMs),
      maximumWallTimeMs: validated.request.budgets.maximumWallTimeMs,
    });

    let prepared: readonly PreparedSide[] = [];
    let preparationFailure: MinimizationCandidateObservation | undefined;
    const syntaxTimeoutMs = Math.min(
      1_000,
      validated.request.budgets.candidateTimeoutMs,
    );
    try {
      if (
        this.#dependencies.now() - startedAtMs + syntaxTimeoutMs <=
        validated.request.budgets.maximumWallTimeMs
      ) {
        prepared = await Promise.all(
          validated.sides.map((side) =>
            this.#prepareSide(side, syntaxTimeoutMs),
          ),
        );
      }
    } catch (error) {
      const failure = classifyWorkerFailure(error);
      preparationFailure = {
        status: failure.status === "timeout" ? "worker-error" : failure.status,
        reproduced: false,
        fingerprint: [`syntax:${failure.status}`],
        summary:
          failure.status === "timeout"
            ? `Syntax setup timed out; this was not counted as an engine timeout: ${failure.message}`
            : failure.message,
      };
    }

    const isCancelled = () => generation !== this.#generation || this.#disposed;
    const evaluate = preparationFailure
      ? async () => preparationFailure
      : validated.request.target.kind === "engine"
        ? this.#engineEvaluator(validated.request, prepared[0], isCancelled)
        : this.#comparisonEvaluator(
            validated.request,
            prepared as readonly [PreparedSide, PreparedSide],
            isCancelled,
          );
    return reduceSubject({
      subject: validated.request.subject,
      targetIdentity: validated.targetIdentity,
      budgets: validated.request.budgets,
      evaluate,
      now: this.#dependencies.now,
      startedAtMs,
      isCancelled,
      onProgress,
    });
  }

  cancel(): void {
    this.#generation += 1;
    for (const runner of this.#syntax.values()) runner.cancel();
    this.#engine.cancel();
  }

  dispose(): void {
    if (this.#disposed) return;
    this.cancel();
    this.#disposed = true;
    for (const runner of this.#syntax.values()) runner.dispose();
    this.#engine.dispose();
  }

  async #prepareSide(
    input: ComparisonSideInput,
    timeoutMs: number,
  ): Promise<PreparedSide> {
    const definition = AVAILABLE_REGEX_FLAVOURS.require(input.flavour);
    const version = resolveRegexFlavourVersion(
      input.flavourVersion,
      definition,
      `${definition.label} minimizer version`,
    ).definition;
    const syntaxRequest: RegexSyntaxRequest = {
      flavour: input.flavour,
      flavourVersion: version.syntaxVersion,
      pattern: input.pattern,
      flags: input.flags,
      options: input.options,
    };
    const runner = this.#syntax.get(input.flavour);
    if (!runner) throw new Error(`Missing ${input.flavour} syntax runner.`);
    const syntax = await runner.parsePattern(syntaxRequest, timeoutMs);
    if (!syntax.accepted) {
      throw new WorkerRequestError(
        "worker-error",
        `${input.flavour} syntax parsing rejected the fixed pattern.`,
      );
    }
    if (syntax.captures.length > DEFAULT_REGEX_LIMITS.maximumCaptureGroups) {
      throw new WorkerRequestError(
        "worker-error",
        `${input.flavour} pattern exceeds the capture-group limit.`,
      );
    }
    return {
      input,
      syntaxRequest,
      captures: syntax.captures,
    };
  }

  #executionRequest(
    request: SubjectMinimizationRequest,
    side: PreparedSide,
    subject: string,
  ): RegexExecutionRequest {
    return {
      flavour: side.input.flavour,
      flavourVersion: side.input.flavourVersion,
      pattern: side.input.pattern,
      flags: side.input.flags,
      options: side.input.options,
      subject,
      captureMetadata: side.captures,
      scanAll: request.target.scanAll,
      maximumMatches: request.maximumMatches,
      maximumCaptureRows: request.maximumCaptureRows,
    };
  }

  async #runSide(
    request: SubjectMinimizationRequest,
    side: PreparedSide,
    subject: string,
    replace: boolean,
  ): Promise<SideRuntime> {
    const execution = this.#executionRequest(request, side, subject);
    try {
      if (replace) {
        const replacement = await this.#engine.replace(
          {
            ...execution,
            replacement: side.input.replacement ?? "",
            maximumOutputBytes: request.maximumOutputBytes,
          },
          request.budgets.candidateTimeoutMs,
        );
        return {
          status: "complete",
          execution: replacement.execution,
          replacement,
        };
      }
      return {
        status: "complete",
        execution: await this.#engine.execute(
          execution,
          request.budgets.candidateTimeoutMs,
        ),
      };
    } catch (error) {
      return classifyWorkerFailure(error);
    }
  }

  #engineEvaluator(
    request: SubjectMinimizationRequest,
    side: PreparedSide | undefined,
    isCancelled: () => boolean,
  ): (subject: string) => Promise<MinimizationCandidateObservation> {
    if (!side || request.target.kind !== "engine") {
      return async () => ({
        status: "worker-error",
        reproduced: false,
        fingerprint: ["setup:missing-side"],
        summary: "The selected engine side was not prepared.",
      });
    }
    const target = request.target;
    let baselineFingerprint: readonly string[] | undefined;
    let baselineEngineIdentity: string | undefined;
    let first = true;
    const replace =
      target.oracle.kind === "unit-test-failure" &&
      target.oracle.expectation.kind === "replacement";

    return async (subject) => {
      if (isCancelled()) {
        return {
          status: "cancelled",
          reproduced: false,
          fingerprint: ["cancelled"],
          summary: "Subject minimization was cancelled.",
        };
      }
      const baselineRun = first;
      first = false;
      const runtime = await this.#runSide(request, side, subject, replace);
      const observedSide = sideObservation(side.input.flavour, runtime);
      if (
        runtime.status === "crash" ||
        runtime.status === "worker-error" ||
        runtime.status === "cancelled"
      ) {
        return fatalObservation(runtime, [observedSide]);
      }
      if (runtime.status === "timeout") {
        let fingerprint: readonly string[];
        let qualifying = false;
        if (target.oracle.kind === "engine-timeout") {
          fingerprint = ["engine:timeout"];
          qualifying = true;
        } else if (
          target.oracle.kind === "unit-test-failure" &&
          target.oracle.expectation.kind !== "must-time-out"
        ) {
          fingerprint = ["unit-test:unexpected-timeout"];
          qualifying = true;
        } else {
          fingerprint = ["engine:timeout"];
        }
        if (baselineRun && qualifying) baselineFingerprint = fingerprint;
        return {
          status: "timeout",
          reproduced:
            qualifying &&
            (baselineRun || sameFingerprint(baselineFingerprint, fingerprint)),
          fingerprint,
          summary: qualifying
            ? "The selected engine hit the exact worker timeout."
            : "The engine timed out, so the selected non-timeout predicate was not reproduced.",
          sides: [observedSide],
        };
      }
      if (runtime.status !== "complete") {
        return fatalObservation(runtime, [observedSide]);
      }

      const currentIdentity = engineIdentity(runtime.execution);
      if (
        !baselineRun &&
        baselineEngineIdentity !== undefined &&
        baselineEngineIdentity !== currentIdentity
      ) {
        return {
          status: "worker-error",
          reproduced: false,
          fingerprint: ["engine:identity-changed"],
          summary: `Engine identity changed from ${baselineEngineIdentity} to ${currentIdentity}; reduction stopped.`,
          sides: [observedSide],
        };
      }
      if (baselineRun) baselineEngineIdentity = currentIdentity;
      if (target.oracle.kind === "engine-timeout") {
        return {
          status: "complete",
          reproduced: false,
          fingerprint: ["engine:completed"],
          summary: "The selected engine completed instead of timing out.",
          sides: [observedSide],
        };
      }

      const evaluation =
        target.oracle.kind === "capture-range-mismatch"
          ? evaluateCaptureRangeMismatch(
              target.oracle,
              runtime.execution,
              subject,
            )
          : evaluateUnitTestFailure(
              target.oracle.expectation,
              runtime.execution,
              runtime.replacement,
              subject,
            );
      if (baselineRun && evaluation.kind === "failure") {
        baselineFingerprint = evaluation.fingerprint;
      }
      return predicateObservation(
        evaluation,
        evaluation.kind === "failure" &&
          (baselineRun ||
            sameFingerprint(baselineFingerprint, evaluation.fingerprint)),
        observedSide,
      );
    };
  }

  #comparisonEvaluator(
    request: SubjectMinimizationRequest,
    sides: readonly [PreparedSide, PreparedSide],
    isCancelled: () => boolean,
  ): (subject: string) => Promise<MinimizationCandidateObservation> {
    const target = request.target;
    if (target.kind !== "comparison-mismatch") {
      return async () => ({
        status: "worker-error",
        reproduced: false,
        fingerprint: ["setup:wrong-target"],
        summary: "The comparison target was not prepared.",
      });
    }
    let first = true;
    let baselineMode: "semantic" | "timeout" | undefined;
    let timeoutFlavour: ComparisonFlavour | undefined;
    let baselineMismatchKinds: readonly string[] | undefined;
    const baselineIdentities = new Map<ComparisonFlavour, string>();

    return async (subject) => {
      if (isCancelled()) {
        return {
          status: "cancelled",
          reproduced: false,
          fingerprint: ["cancelled"],
          summary: "Subject minimization was cancelled.",
        };
      }
      const baselineRun = first;
      first = false;
      const runtimes = await Promise.all(
        sides.map((side) =>
          this.#runSide(request, side, subject, target.operation === "replace"),
        ),
      );
      const observedSides = sides.map((side, index) =>
        sideObservation(
          side.input.flavour,
          runtimes[index] ??
            ({
              status: "worker-error",
              message: "Missing comparison side result.",
            } as const),
        ),
      );
      const fatal = runtimes.find(
        (runtime): runtime is SideRuntimeFailure =>
          runtime?.status === "crash" ||
          runtime?.status === "worker-error" ||
          runtime?.status === "cancelled",
      );
      if (fatal) return fatalObservation(fatal, observedSides);

      const timeouts = runtimes
        .map((runtime, index) => ({ runtime, side: sides[index] }))
        .filter(
          (
            value,
          ): value is {
            readonly runtime: SideRuntimeFailure & {
              readonly status: "timeout";
            };
            readonly side: PreparedSide;
          } => value.runtime?.status === "timeout" && value.side !== undefined,
        );
      const completes = runtimes
        .map((runtime, index) => ({ runtime, side: sides[index] }))
        .filter(
          (
            value,
          ): value is {
            readonly runtime: SideRuntimeComplete;
            readonly side: PreparedSide;
          } => value.runtime?.status === "complete" && value.side !== undefined,
        );

      if (baselineRun) {
        if (timeouts.length === 1 && completes.length === 1) {
          const complete = completes[0];
          const timeout = timeouts[0];
          if (!complete || !timeout) {
            throw new Error("Incomplete comparison baseline.");
          }
          const authoritative = compareSemanticResults(
            {
              execution: complete.runtime.execution,
              ...(complete.runtime.replacement
                ? { replacement: complete.runtime.replacement }
                : {}),
            },
            {
              execution: complete.runtime.execution,
              ...(complete.runtime.replacement
                ? { replacement: complete.runtime.replacement }
                : {}),
            },
          );
          if (authoritative.kind !== "same") {
            return {
              status: "inconclusive",
              reproduced: false,
              fingerprint: ["comparison:timeout-with-incomplete-peer"],
              summary:
                "One engine timed out, but the peer result was not complete and authoritative.",
              sides: observedSides,
            };
          }
          baselineMode = "timeout";
          timeoutFlavour = timeout.side.input.flavour;
          baselineIdentities.set(
            complete.side.input.flavour,
            engineIdentity(complete.runtime.execution),
          );
          return {
            status: "timeout",
            reproduced: true,
            fingerprint: [`comparison:timeout:${timeoutFlavour}`],
            summary: `${timeoutFlavour} timed out while the other selected engine completed authoritatively.`,
            sides: observedSides,
          };
        }
        if (timeouts.length > 0) {
          return {
            status: "timeout",
            reproduced: false,
            fingerprint: ["comparison:both-timeout"],
            summary:
              "Both engines timed out; this is not a one-sided comparison mismatch.",
            sides: observedSides,
          };
        }
      }

      if (baselineMode === "timeout") {
        if (timeouts.length !== 1 || completes.length !== 1) {
          return {
            status: timeouts.length > 0 ? "timeout" : "complete",
            reproduced: false,
            fingerprint: ["comparison:timeout-shape-changed"],
            summary:
              "The candidate did not preserve the same one-sided timeout.",
            sides: observedSides,
          };
        }
        const timeout = timeouts[0];
        const complete = completes[0];
        if (!timeout || !complete) {
          throw new Error("Incomplete comparison timeout candidate.");
        }
        const authoritative = compareSemanticResults(
          {
            execution: complete.runtime.execution,
            ...(complete.runtime.replacement
              ? { replacement: complete.runtime.replacement }
              : {}),
          },
          {
            execution: complete.runtime.execution,
            ...(complete.runtime.replacement
              ? { replacement: complete.runtime.replacement }
              : {}),
          },
        );
        const expectedIdentity = baselineIdentities.get(
          complete.side.input.flavour,
        );
        const actualIdentity = engineIdentity(complete.runtime.execution);
        if (
          expectedIdentity !== undefined &&
          expectedIdentity !== actualIdentity
        ) {
          return {
            status: "worker-error",
            reproduced: false,
            fingerprint: ["engine:identity-changed"],
            summary: `Comparison peer identity changed from ${expectedIdentity} to ${actualIdentity}.`,
            sides: observedSides,
          };
        }
        const reproduced =
          timeout.side.input.flavour === timeoutFlavour &&
          authoritative.kind === "same";
        return {
          status: "timeout",
          reproduced,
          fingerprint: [`comparison:timeout:${timeout.side.input.flavour}`],
          summary: reproduced
            ? "The exact one-sided timeout mismatch was preserved."
            : "The candidate did not preserve an authoritative peer completion.",
          sides: observedSides,
        };
      }

      if (timeouts.length > 0 || completes.length !== 2) {
        return {
          status: timeouts.length > 0 ? "timeout" : "inconclusive",
          reproduced: false,
          fingerprint: ["comparison:not-complete"],
          summary:
            "Both selected engines must complete for a semantic mismatch candidate.",
          sides: observedSides,
        };
      }
      const left = completes[0];
      const right = completes[1];
      if (!left || !right)
        throw new Error("Missing completed comparison side.");
      for (const complete of completes) {
        const current = engineIdentity(complete.runtime.execution);
        const flavour = complete.side.input.flavour;
        const expected = baselineIdentities.get(flavour);
        if (!baselineRun && expected !== undefined && expected !== current) {
          return {
            status: "worker-error",
            reproduced: false,
            fingerprint: ["engine:identity-changed"],
            summary: `${flavour} engine identity changed from ${expected} to ${current}.`,
            sides: observedSides,
          };
        }
        if (baselineRun) baselineIdentities.set(flavour, current);
      }
      const semantic = compareSemanticResults(
        {
          execution: left.runtime.execution,
          ...(left.runtime.replacement
            ? { replacement: left.runtime.replacement }
            : {}),
        } satisfies SemanticSideResult,
        {
          execution: right.runtime.execution,
          ...(right.runtime.replacement
            ? { replacement: right.runtime.replacement }
            : {}),
        } satisfies SemanticSideResult,
      );
      if (baselineRun && semantic.kind === "mismatch") {
        baselineMode = "semantic";
        baselineMismatchKinds = semantic.mismatchKinds;
      }
      const exactMismatch =
        semantic.kind === "mismatch" &&
        (baselineRun ||
          sameFingerprint(baselineMismatchKinds, semantic.mismatchKinds));
      return {
        status: semantic.kind === "inconclusive" ? "inconclusive" : "complete",
        reproduced: exactMismatch,
        fingerprint:
          semantic.kind === "mismatch"
            ? ["comparison:semantic-mismatch", ...semantic.mismatchKinds]
            : [`comparison:${semantic.kind}`],
        summary:
          semantic.kind === "mismatch" && !exactMismatch
            ? `${semantic.summary} The mismatch class changed, so this candidate was rejected.`
            : semantic.summary,
        mismatchKinds: semantic.mismatchKinds,
        sides: observedSides,
      };
    };
  }
}
