import type { CheckFailure, JsonValue } from "../types";

export interface ContentCssExpectation {
  attr?: string;
  kind: "css";
  matcher: ValueExpectation;
  selector: string;
}

export type ContentExpectation =
  | ContentCssExpectation
  | ContentJsonExpectation
  | ContentValueExpectation
  | ContentXpathExpectation;

export type ContentExpectations = ContentExpectation[];

export interface ContentJsonExpectation {
  kind: "json";
  matcher: ValueExpectation;
  path: string;
}

export interface ContentValueExpectation {
  kind: "value";
  matcher: ValueExpectation;
}

export interface ContentXpathExpectation {
  kind: "xpath";
  matcher: ValueExpectation;
  path: string;
}

export interface ExpectationResult {
  failure: CheckFailure | null;
  matched: boolean;
}

export interface KeyedExpectation {
  key: string;
  matcher: ValueExpectation;
}

export type KeyedExpectations = KeyedExpectation[];

export interface RawContentCssExpectation extends ValueMatcher {
  attr?: string;
  selector: string;
}

export type RawContentExpectation =
  | ValueMatcher
  | { css: RawContentCssExpectation }
  | { json: RawContentJsonExpectation }
  | { xpath: RawContentXpathExpectation };

export type RawContentExpectations = RawContentExpectation[];

export interface RawContentJsonExpectation extends ValueMatcher {
  path: string;
}

export interface RawContentXpathExpectation extends ValueMatcher {
  path: string;
}

export type RawKeyedExpectations = Record<string, RawValueExpectation>;

export type RawValueExpectation = ValueMatcher | ValueMatcherPrimitive;

export type ValueExpectation = ValueMatcher;

export interface ValueMatcher {
  contains?: string;
  empty?: boolean;
  equals?: JsonValue;
  exists?: boolean;
  gt?: number;
  gte?: number;
  lt?: number;
  lte?: number;
  regex?: string;
}

export type ValueMatcherPrimitive = boolean | null | number | string;
