import { AssertionError } from "assert";
import * as Process from "process";
import { AsymmetricMatchers, JestExpect } from "@jest/expect";
import { Circus } from "@jest/types";
import { FailedAssertion, Status } from "@jest/test-result";

//#region src/jasmine/CallTracker.d.ts
/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */
type Context = {
  object: unknown;
  args: Array<unknown>;
  returnValue?: unknown;
};
declare class CallTracker {
  track: (context: Context) => void;
  any: () => boolean;
  count: () => number;
  argsFor: (index: number) => Array<unknown>;
  all: () => Array<Context>;
  allArgs: () => Array<unknown>;
  first: () => Context;
  mostRecent: () => Context;
  reset: () => void;
  constructor();
}
//#endregion
//#region src/queueRunner.d.ts
/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
type Options$1 = {
  clearTimeout: (typeof globalThis)['clearTimeout'];
  fail: (error: Error) => void;
  onException: (error: Error) => void;
  queueableFns: Array<QueueableFn>;
  setTimeout: (typeof globalThis)['setTimeout'];
  userContext: unknown;
};
interface DoneFn {
  (error?: any): void;
  fail: (error: Error) => void;
}
type QueueableFn = {
  fn: (done: DoneFn) => void;
  timeout?: () => number;
  initError?: Error;
};
type PromiseCallback = (() => void | PromiseLike<void>) | undefined | null;
declare function queueRunner(options: Options$1): PromiseLike<void> & {
  cancel: () => void;
  catch: (onRejected?: PromiseCallback) => Promise<void>;
};
//#endregion
//#region src/ExpectationFailed.d.ts
/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */
declare class ExpectationFailed extends Error {}
//#endregion
//#region src/expectationResultFactory.d.ts
type Options = {
  matcherName: string;
  passed: boolean;
  actual?: any;
  error?: any;
  expected?: any;
  message?: string | null;
};
declare function expectationResultFactory(options: Options, initError?: Error): FailedAssertion;
//#endregion
//#region src/jasmine/Spec.d.ts
type Attributes$1 = {
  id: string;
  resultCallback: (result: Spec['result']) => void;
  description: Circus.TestNameLike;
  throwOnExpectationFailure: unknown;
  getTestPath: () => string;
  queueableFn: QueueableFn;
  beforeAndAfterFns: () => {
    befores: Array<QueueableFn>;
    afters: Array<QueueableFn>;
  };
  userContext: () => unknown;
  onStart: (context: Spec) => void;
  getSpecName: (spec: Spec) => string;
  queueRunnerFactory: typeof queueRunner;
};
type SpecResult = {
  id: string;
  description: string;
  fullName: string;
  duration?: number;
  failedExpectations: Array<FailedAssertion>;
  testPath: string;
  passedExpectations: Array<ReturnType<typeof expectationResultFactory>>;
  pendingReason: string;
  status: Status;
  __callsite?: {
    getColumnNumber: () => number;
    getLineNumber: () => number;
  };
};
declare class Spec {
  id: string;
  description: string;
  resultCallback: (result: SpecResult) => void;
  queueableFn: QueueableFn;
  beforeAndAfterFns: () => {
    befores: Array<QueueableFn>;
    afters: Array<QueueableFn>;
  };
  userContext: () => unknown;
  onStart: (spec: Spec) => void;
  getSpecName: (spec: Spec) => string;
  queueRunnerFactory: typeof queueRunner;
  throwOnExpectationFailure: boolean;
  initError: Error;
  result: SpecResult;
  disabled?: boolean;
  currentRun?: ReturnType<typeof queueRunner>;
  markedTodo?: boolean;
  markedPending?: boolean;
  expand?: boolean;
  static pendingSpecExceptionMessage: string;
  static isPendingSpecException(e: Error): boolean;
  constructor(attrs: Attributes$1);
  addExpectationResult(passed: boolean, data: Options, isError?: boolean): void;
  execute(onComplete?: () => void, enabled?: boolean): void;
  cancel(): void;
  onException(error: ExpectationFailed | AssertionErrorWithStack): void;
  disable(): void;
  pend(message?: string): void;
  todo(): void;
  getResult(): SpecResult;
  status(enabled?: boolean): "disabled" | "todo" | "pending" | "failed" | "passed";
  isExecutable(): boolean;
  getFullName(): string;
  isAssertionError(error: Error): boolean;
}
//#endregion
//#region src/jasmine/Suite.d.ts
type SuiteResult = {
  id: string;
  description: string;
  fullName: string;
  failedExpectations: Array<ReturnType<typeof expectationResultFactory>>;
  testPath: string;
  status?: string;
};
type Attributes = {
  id: string;
  parentSuite?: Suite;
  description: Circus.TestNameLike;
  throwOnExpectationFailure?: boolean;
  getTestPath: () => string;
};
declare class Suite {
  id: string;
  parentSuite?: Suite;
  description: Circus.TestNameLike;
  throwOnExpectationFailure: boolean;
  beforeFns: Array<QueueableFn>;
  afterFns: Array<QueueableFn>;
  beforeAllFns: Array<QueueableFn>;
  afterAllFns: Array<QueueableFn>;
  disabled: boolean;
  children: Array<Suite | Spec>;
  result: SuiteResult;
  sharedContext?: object;
  markedPending: boolean;
  markedTodo: boolean;
  isFocused: boolean;
  constructor(attrs: Attributes);
  getFullName(): string;
  disable(): void;
  pend(_message?: string): void;
  beforeEach(fn: QueueableFn): void;
  beforeAll(fn: QueueableFn): void;
  afterEach(fn: QueueableFn): void;
  afterAll(fn: QueueableFn): void;
  addChild(child: Suite | Spec): void;
  status(): "disabled" | "pending" | "failed" | "finished";
  isExecutable(): boolean;
  canBeReentered(): boolean;
  getResult(): SuiteResult;
  sharedUserContext(): object;
  clonedSharedUserContext(): object;
  onException(...args: Parameters<Spec['onException']>): void;
  addExpectationResult(...args: Parameters<Spec['addExpectationResult']>): void;
  execute(..._args: Array<any>): void;
}
//#endregion
//#region src/jasmine/Env.d.ts
declare function jasmineEnv(j$: Jasmine): {
  new (): {
    specFilter: (spec: Spec) => boolean;
    catchExceptions: (value: unknown) => boolean;
    throwOnExpectationFailure: (value: unknown) => void;
    catchingExceptions: () => boolean;
    topSuite: () => Suite;
    fail: (error: Error | AssertionErrorWithStack) => void;
    pending: (message: string) => void;
    afterAll: (afterAllFunction: QueueableFn["fn"], timeout?: number) => void;
    fit: (description: Circus.TestNameLike, fn: QueueableFn["fn"], timeout?: number) => Spec;
    throwingExpectationFailures: () => boolean;
    randomizeTests: (value: unknown) => void;
    randomTests: () => boolean;
    seed: (value: unknown) => unknown;
    execute: (runnablesToRun?: Array<string>, suiteTree?: Suite) => Promise<void>;
    fdescribe: (description: Circus.TestNameLike, specDefinitions: SpecDefinitionsFn) => Suite;
    spyOn: (obj: Record<string, Spy>, methodName: string, accessType?: keyof PropertyDescriptor) => Spy;
    beforeEach: (beforeEachFunction: QueueableFn["fn"], timeout?: number) => void;
    afterEach: (afterEachFunction: QueueableFn["fn"], timeout?: number) => void;
    clearReporters: () => void;
    addReporter: (reporterToAdd: Reporter) => void;
    it: (description: Circus.TestNameLike, fn: QueueableFn["fn"], timeout?: number) => Spec;
    xdescribe: (description: Circus.TestNameLike, specDefinitions: SpecDefinitionsFn) => Suite;
    xit: (description: Circus.TestNameLike, fn: QueueableFn["fn"], timeout?: number) => Spec;
    beforeAll: (beforeAllFunction: QueueableFn["fn"], timeout?: number) => void;
    todo: () => Spec;
    provideFallbackReporter: (reporterToAdd: Reporter) => void;
    allowRespy: (allow: boolean) => void;
    describe: (description: Circus.TestNameLike, specDefinitions: SpecDefinitionsFn) => Suite;
  };
};
//#endregion
//#region src/jasmine/Timer.d.ts
/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */
declare class Timer {
  start: () => void;
  elapsed: () => number;
  constructor(options?: {
    now?: () => number;
  });
}
//#endregion
//#region src/jasmine/JsApiReporter.d.ts
declare class JsApiReporter implements Reporter {
  started: boolean;
  finished: boolean;
  runDetails: RunDetails;
  jasmineStarted: (runDetails: RunDetails) => void;
  jasmineDone: (runDetails: RunDetails) => void;
  status: () => unknown;
  executionTime: () => unknown;
  suiteStarted: (result: SuiteResult) => void;
  suiteDone: (result: SuiteResult) => void;
  suiteResults: (index: number, length: number) => Array<SuiteResult>;
  suites: () => Record<string, SuiteResult>;
  specResults: (index: number, length: number) => Array<SpecResult>;
  specDone: (result: SpecResult) => void;
  specs: () => Array<SpecResult>;
  specStarted: (spec: SpecResult) => void;
  constructor(options: {
    timer?: Timer;
  });
}
//#endregion
//#region src/jasmine/ReportDispatcher.d.ts
declare class ReportDispatcher implements Reporter {
  addReporter: (reporter: Reporter) => void;
  provideFallbackReporter: (reporter: Reporter) => void;
  clearReporters: () => void;
  jasmineDone: (runDetails: RunDetails) => void;
  jasmineStarted: (runDetails: RunDetails) => void;
  specDone: (result: SpecResult) => void;
  specStarted: (spec: SpecResult) => void;
  suiteDone: (result: SuiteResult) => void;
  suiteStarted: (result: SuiteResult) => void;
  constructor(methods: Array<keyof Reporter>);
}
//#endregion
//#region src/jasmine/SpyStrategy.d.ts
/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 */
declare class SpyStrategy {
  identity: () => string;
  exec: (...args: Array<any>) => unknown;
  callThrough: () => unknown;
  returnValue: (value: unknown) => unknown;
  returnValues: () => unknown;
  throwError: (something: string | Error) => unknown;
  callFake: (fn: Function) => unknown;
  stub: (fn: Function) => unknown;
  constructor({
    name,
    fn,
    getSpy
  }?: {
    name?: string;
    fn?: Function;
    getSpy?: () => unknown;
  });
}
//#endregion
//#region src/jasmine/createSpy.d.ts
interface Fn extends Record<string, unknown> {
  (): unknown;
}
declare function createSpy(name: string, originalFn: Fn): Spy;
//#endregion
//#region src/jasmine/spyRegistry.d.ts
declare class SpyRegistry {
  allowRespy: (allow: unknown) => void;
  spyOn: (obj: Record<string, Spy>, methodName: string, accessType?: keyof PropertyDescriptor) => Spy;
  clearSpies: () => void;
  respy: unknown;
  private readonly _spyOnProperty;
  constructor({
    currentSpies
  }?: {
    currentSpies?: () => Array<Spy>;
  });
}
//#endregion
//#region src/types.d.ts
type SpecDefinitionsFn = () => void;
interface AssertionErrorWithStack extends AssertionError {
  stack: string;
}
type RunDetails = {
  totalSpecsDefined?: number;
  failedExpectations?: SuiteResult['failedExpectations'];
};
type Reporter = {
  jasmineDone: (runDetails: RunDetails) => void;
  jasmineStarted: (runDetails: RunDetails) => void;
  specDone: (result: SpecResult) => void;
  specStarted: (spec: SpecResult) => void;
  suiteDone: (result: SuiteResult) => void;
  suiteStarted: (result: SuiteResult) => void;
};
interface Spy extends Record<string, any> {
  (this: Record<string, unknown>, ...args: Array<any>): unknown;
  and: SpyStrategy;
  calls: CallTracker;
  restoreObjectToOriginalState?: () => void;
}
type JasmineMatcher = {
  (matchersUtil: unknown, context: unknown): JasmineMatcher;
  compare(...args: Array<unknown>): unknown;
  negativeCompare(...args: Array<unknown>): unknown;
};
type JasmineMatchersObject = {
  [id: string]: JasmineMatcher;
};
type Jasmine = {
  _DEFAULT_TIMEOUT_INTERVAL: number;
  DEFAULT_TIMEOUT_INTERVAL: number;
  currentEnv_: ReturnType<typeof jasmineEnv>['prototype'];
  getEnv: () => ReturnType<typeof jasmineEnv>['prototype'];
  createSpy: typeof createSpy;
  Env: ReturnType<typeof jasmineEnv>;
  JsApiReporter: typeof JsApiReporter;
  ReportDispatcher: typeof ReportDispatcher;
  Spec: typeof Spec;
  SpyRegistry: typeof SpyRegistry;
  Suite: typeof Suite;
  Timer: typeof Timer;
  version: string;
  testPath: string;
  addMatchers: (matchers: JasmineMatchersObject) => void;
} & AsymmetricMatchers & {
  process: typeof Process;
};
declare global {
  namespace NodeJS {
    interface Global {
      expect: JestExpect;
      jasmine: Jasmine;
    }
  }
}
declare module '@jest/types' {
  namespace Global {
    interface GlobalAdditions {
      jasmine: Jasmine;
      fail: () => void;
      pending: () => void;
      spyOn: () => void;
      spyOnProperty: () => void;
    }
  }
}
//#endregion
//#region src/jasmine/jasmineLight.d.ts
declare const testTimeoutSymbol: unique symbol;
declare global {
  namespace NodeJS {
    interface Global {
      [testTimeoutSymbol]: number;
    }
  }
}
declare const create: (createOptions: Record<string, any>) => Jasmine;
declare const _interface: (jasmine: Jasmine, env: any) => {
  describe(description: string, specDefinitions: SpecDefinitionsFn): any;
  xdescribe(description: string, specDefinitions: SpecDefinitionsFn): any;
  fdescribe(description: string, specDefinitions: SpecDefinitionsFn): any;
  it(): any;
  xit(): any;
  fit(): any;
  beforeEach(): any;
  afterEach(): any;
  beforeAll(): any;
  afterAll(): any;
  pending(): any;
  fail(): any;
  spyOn(obj: Record<string, any>, methodName: string, accessType?: string): any;
  jsApiReporter: JsApiReporter;
  jasmine: Jasmine;
};
//#endregion
export { _interface, create };