import type { RegexEngineOptions } from "../model/flavour";
import type { RegexTestCase } from "../tests/test-case.types";

export const ECMASCRIPT_FORMATTER_ID = "regex-tools-ecmascript-literal-escapes";
export const ECMASCRIPT_FORMATTER_VERSION = "1";

export type PatternFormatChangeKind =
  "literal-slash" | "raw-control" | "raw-line-terminator";

export interface PatternFormatChange {
  readonly kind: PatternFormatChangeKind;
  readonly startUtf16: number;
  readonly endUtf16: number;
  readonly before: string;
  readonly after: string;
  readonly explanation: string;
}

export interface PatternFormatPreview {
  readonly formatter: {
    readonly id: typeof ECMASCRIPT_FORMATTER_ID;
    readonly version: typeof ECMASCRIPT_FORMATTER_VERSION;
    readonly flavour: "ecmascript";
    readonly syntaxProvider: string;
    readonly syntaxProviderVersion: string;
  };
  readonly sourcePattern: string;
  readonly formattedPattern: string;
  readonly changed: boolean;
  readonly changes: readonly PatternFormatChange[];
  readonly totalChanges: number;
  readonly changesTruncated: boolean;
  readonly withinPatternLimit: boolean;
  readonly warnings: readonly string[];
}

export interface PatternFormatValidationInput {
  readonly flavour: "ecmascript";
  readonly flavourVersion?: string;
  readonly sourcePattern: string;
  readonly formattedPattern: string;
  readonly flags: readonly string[];
  readonly options: RegexEngineOptions;
  readonly subject: string;
  readonly replacement: string;
  readonly scanAll: boolean;
  readonly timeoutMs: number;
  readonly tests: readonly RegexTestCase[];
}

export type PatternFormatRuntimeStatus =
  "complete" | "timeout" | "cancelled" | "crash" | "worker-error";

export interface PatternFormatRuntimeObservation {
  readonly status: PatternFormatRuntimeStatus;
  readonly engineIdentity?: string;
  readonly assertionPassed?: boolean;
  readonly message: string;
}

export type PatternFormatComparisonStatus =
  "same" | "different" | "inconclusive";

export interface PatternFormatSnapshotCheck {
  readonly comparison: PatternFormatComparisonStatus;
  readonly before: PatternFormatRuntimeObservation;
  readonly after: PatternFormatRuntimeObservation;
  readonly summary: string;
  readonly mismatchKinds: readonly string[];
}

export interface PatternFormatTestCheck extends PatternFormatSnapshotCheck {
  readonly testId: string;
  readonly name: string;
}

export interface PatternFormatDifference {
  readonly scope: "syntax" | "current-subject" | "unit-test";
  readonly code: string;
  readonly summary: string;
  readonly testId?: string;
}

export interface PatternFormatValidationResult {
  readonly status: "equivalent" | "different" | "inconclusive";
  readonly canApply: boolean;
  readonly sourceSyntaxAccepted: boolean;
  readonly formattedSyntaxAccepted: boolean;
  readonly captureShapePreserved: boolean;
  readonly current: PatternFormatSnapshotCheck;
  readonly tests: readonly PatternFormatTestCheck[];
  readonly applicableTestCount: number;
  readonly skippedTestCount: number;
  readonly completedTestCount: number;
  readonly differences: readonly PatternFormatDifference[];
  readonly elapsedMs: number;
  readonly notices: readonly string[];
}
