/// <reference types="jasmine" />
import { Observable } from 'rxjs';
import { AddObservableSpyMethods, AddPromiseSpyMethods, Func, AddAccessorsSpies, CreateSyncAutoSpy, CreateObservableAutoSpy, CreatePromiseAutoSpy } from '@hirez_io/auto-spies-core';
export type Spy<ClassToSpyOn> = AddJasmineAutoSpies<ClassToSpyOn> & AddAccessorsSpies<ClassToSpyOn, jasmine.Spy>;
type AddJasmineAutoSpies<ClassToSpyOn> = {
    [Key in keyof ClassToSpyOn]: ClassToSpyOn[Key] extends Func ? AddSpyMethodsByReturnTypes<ClassToSpyOn[Key]> : ClassToSpyOn[Key] extends Observable<infer ObservableReturnType> ? ClassToSpyOn[Key] & AddObservableSpyMethods<ObservableReturnType> : ClassToSpyOn[Key];
};
export type AddSpyMethodsByReturnTypes<Method extends Func> = Method & (Method extends (...args: any[]) => infer ReturnType ? ReturnType extends Promise<infer PromiseReturnType> ? CreatePromiseAutoSpy<jasmine.Spy<Method>, AddPromisesToJasmineFunctionSpy<PromiseReturnType>, Method> : ReturnType extends Observable<infer ObservableReturnType> ? CreateObservableAutoSpy<jasmine.Spy<Method>, AddObservablesToJasmineFunctionSpy<ObservableReturnType>, Method> : CreateSyncAutoSpy<Method, jasmine.Spy<Method>, AddCalledWithToJasmineFunctionSpy<Method>> : never);
type AddPromisesToJasmineFunctionSpy<PromiseReturnType> = {
    and: AddPromiseSpyMethods<PromiseReturnType>;
};
type AddObservablesToJasmineFunctionSpy<ObservableReturnType> = {
    and: AddObservableSpyMethods<ObservableReturnType>;
};
export interface AddCalledWithToJasmineFunctionSpy<Method extends Func> {
    calledWith(...args: Parameters<Method>): {
        returnValue: (value: ReturnType<Method>) => void;
    };
    mustBeCalledWith(...args: Parameters<Method>): {
        returnValue: (value: ReturnType<Method>) => void;
    };
}
export {};
