import type { RegexDiagnostic } from "./diagnostics";
import type {
  RegexEngineInfo,
  RegexEngineOptions,
  RegexFlavourId,
} from "./flavour";
import type { RegexExecutionFlags } from "./match";

export interface Pcre2TraceRequest {
  readonly flavour: RegexFlavourId;
  readonly pattern: string;
  readonly flags: readonly string[];
  readonly options?: RegexEngineOptions;
  readonly subject: string;
  readonly maximumTraceEvents: number;
  readonly maximumTraceBytes: number;
}

export interface Pcre2TraceReportedEvent {
  readonly provenance: "reported";
  readonly calloutNumber: number;
  readonly patternPosition: {
    readonly utf16: number;
    readonly nativeByte: number;
  };
  readonly nextPatternItem: {
    readonly startUtf16: number;
    readonly endUtf16: number;
    readonly startNativeByte: number;
    readonly endNativeByte: number;
  };
  readonly subjectPosition: {
    readonly utf16: number;
    readonly nativeByte: number;
  };
  readonly captureTop: number;
  readonly captureLast: number;
  readonly mark?: string;
}

export interface Pcre2TraceMovement {
  readonly provenance: "derived";
  readonly classification:
    "first-event" | "forward" | "same-position" | "apparent-backtrack";
  readonly subjectDeltaBytes: number;
  readonly explanation: string;
}

export interface Pcre2TraceEvent {
  readonly eventNumber: number;
  readonly reported: Pcre2TraceReportedEvent;
  readonly movement: Pcre2TraceMovement;
}

export interface Pcre2TraceResult {
  readonly accepted: boolean;
  readonly engine: RegexEngineInfo;
  readonly flags: RegexExecutionFlags;
  readonly events: readonly Pcre2TraceEvent[];
  readonly diagnostics: readonly RegexDiagnostic[];
  readonly elapsedMs: number;
  readonly truncated: boolean;
  readonly marksTruncated: boolean;
  readonly totalEventCount: number;
  readonly traceBytes: number;
  readonly nativeMatchStatus: number;
  readonly matched: boolean;
  readonly lastCompleteEvent?: number;
}
