import type { RegexEngineOptions, RegexFlavourId } from "../model/flavour";
import type { RegexResourceLimits } from "../execution/request-limits";
import type { GeneratedCaseProvenance } from "../generation/generation.types";

export const MAXIMUM_REGEX_TESTS = 1_000;
export const MAXIMUM_REGEX_TEST_NAME_UTF16 = 256;
export const MAXIMUM_REGEX_TEST_PATTERN_UTF16 = 64 * 1024;
export const MAXIMUM_REGEX_TEST_SUBJECT_UTF16 = 16 * 1024 * 1024;
export const MAXIMUM_REGEX_TEST_EXPECTED_UTF16 = 16 * 1024 * 1024;
export const MAXIMUM_REGEX_TEST_CAPTURE_NAME_UTF16 = 256;
export const MAXIMUM_REGEX_TEST_RESULT_MESSAGE_BYTES = 2 * 1024;

export type RegexTestExpectation =
  | { readonly kind: "should-match" }
  | { readonly kind: "should-not-match" }
  | { readonly kind: "match-count"; readonly count: number }
  | {
      readonly kind: "full-match";
      readonly matchIndex: number;
      readonly value: string;
    }
  | {
      readonly kind: "capture";
      readonly matchIndex: number;
      readonly groupNumber?: number;
      readonly groupName?: string;
      readonly status: "participated" | "did-not-participate" | "matched-empty";
      readonly value?: string;
    }
  | { readonly kind: "replacement"; readonly expected: string }
  | { readonly kind: "must-complete-within"; readonly milliseconds: number }
  | { readonly kind: "must-time-out" };

export interface RegexTestCase {
  readonly id: string;
  readonly name: string;
  readonly enabled: boolean;
  readonly flavour: RegexFlavourId;
  readonly flavourVersion?: string;
  readonly pattern: string;
  readonly flags: readonly string[];
  readonly options: RegexEngineOptions;
  /** Explicitly iterate matches even when the saved user flags omit g/y. */
  readonly scanAll?: boolean;
  readonly subject: string;
  readonly replacement?: string;
  readonly expectation: RegexTestExpectation;
  readonly resourceLimits?: Partial<RegexResourceLimits>;
  /** Present only while the test is unchanged from an engine-verified candidate. */
  readonly generation?: GeneratedCaseProvenance;
}

export interface RegexTestResult {
  readonly testId: string;
  readonly passed: boolean;
  readonly elapsedMs: number;
  readonly message: string;
  readonly engineIdentity?: string;
  readonly timedOut: boolean;
}
