import type { RegexTestExpectation } from "./test-case.types";
import { MAXIMUM_REGEX_TEST_EXPECTED_UTF16 } from "./test-case.types";

export interface ReplacementResultDraftDecision {
  readonly expectation?: Extract<
    RegexTestExpectation,
    { readonly kind: "replacement" | "should-match" }
  >;
  readonly notice?: string;
}

export function chooseReplacementResultDraft({
  output,
  resultTruncated,
  matchCount,
  canStore,
  maximumExpectedUtf16 = MAXIMUM_REGEX_TEST_EXPECTED_UTF16,
}: {
  readonly output: string;
  readonly resultTruncated: boolean;
  readonly matchCount: number;
  readonly canStore: (expectation: RegexTestExpectation) => boolean;
  readonly maximumExpectedUtf16?: number;
}): ReplacementResultDraftDecision {
  let notice: string | undefined;
  if (!resultTruncated) {
    if (output.length <= maximumExpectedUtf16) {
      const expectation = { kind: "replacement", expected: output } as const;
      if (canStore(expectation)) return { expectation };
      notice =
        "An exact replacement assertion is not offered because it would exceed the 32 MiB test-suite state limit.";
    } else {
      notice = `An exact replacement assertion is not offered because the output exceeds the ${maximumExpectedUtf16.toLocaleString()} UTF-16 unit expected-value limit.`;
    }
  }

  if (matchCount > 0) {
    const expectation = { kind: "should-match" } as const;
    if (canStore(expectation))
      return { expectation, ...(notice ? { notice } : {}) };
    notice =
      "A current-result assertion is not offered because it would exceed the 32 MiB test-suite state limit.";
  }
  return notice ? { notice } : {};
}
