import { InstalledClock } from '@sinonjs/fake-timers';
import { ExecutionContext } from 'ava';
import { FastifyInstance } from 'fastify';
import { Adapter, AdapterDependencies } from '../adapter';
import { Cache, LocalCache } from '../cache';
import { ResponseCache } from '../cache/response';
import { EmptyCustomSettings, SettingsDefinitionMap } from '../config';
import { Transport, TransportDependencies, TransportGenerics, WebSocketClassProvider } from '../transports';
import { EmptyInputParameters, TypeFromDefinition } from '../validation/input-params';
import { AdapterRequest, AdapterResponse, PartialAdapterResponse } from './index';
export { WebSocket as MockWebsocket, Server as MockWebsocketServer } from 'mock-socket';
export type NopTransportTypes = {
    Parameters: EmptyInputParameters;
    Response: {
        Data: null;
        Result: null;
    };
    Settings: EmptyCustomSettings;
};
export declare class NopTransport<T extends TransportGenerics = NopTransportTypes> implements Transport<T> {
    name: string;
    responseCache: ResponseCache<T>;
    initialize(dependencies: TransportDependencies<T>, adapterSettings: T['Settings'], endpointName: string, transportName: string): Promise<void>;
    foregroundExecute(_: AdapterRequest<TypeFromDefinition<T['Parameters']>>): Promise<void | AdapterResponse<T['Response']>>;
}
export declare class MockCache extends LocalCache {
    constructor(maxItems: number);
    private awaitingPromiseResolve?;
    waitForNextSet(): Promise<unknown>;
    set(key: string, value: Readonly<unknown>, ttl: number): Promise<void>;
}
export declare function runPeriodicAsyncBackgroundExecution(clock: InstalledClock, { interval, times, stepValidation, }: {
    interval: number;
    times: number;
    stepValidation: (iteration: number) => boolean;
}): Promise<void>;
export declare function runAllUntil(clock: InstalledClock, isComplete: () => boolean): Promise<void>;
export declare function runAllUntilTime(clock: InstalledClock, time: number): Promise<void>;
export declare class RedisMock {
    store: LocalCache<string>;
    keys: {
        [key: string]: string;
    };
    get(key: string): Promise<string | undefined>;
    del(key: string): Promise<void>;
    set(key: string, value: string, px: 'PX', ttl: number): Promise<void>;
    multi(): CommandChainMock;
    defineCommand(_name: 'setExternalAdapterResponse', _options: {
        lua: string;
        numberOfKeys: number;
    }): void;
    setExternalAdapterResponse(key: string, value: string, ttl: number): Promise<void>;
    evalsha(...args: [string, number, [string, string, number]]): 0 | 1;
    pexpire(): void;
    quit(): void;
}
declare class CommandChainMock {
    private redisMock;
    promises: Promise<unknown>[];
    constructor(redisMock: RedisMock);
    set(key: string, value: string, px: 'PX', ttl: number): this;
    setExternalAdapterResponse(key: string, value: string, ttl: number): this;
    exec(): Promise<unknown[]>;
}
export declare function assertEqualResponses(t: ExecutionContext, actual: AdapterResponse, expected: PartialAdapterResponse & {
    statusCode: number;
}): void;
declare class TestMetrics {
    map: Map<string, number>;
    private replaceQuotes;
    constructor(data: string);
    private get;
    assert(t: ExecutionContext, params: {
        name: string;
        labels?: Record<string, string>;
        expectedValue: number;
    }): void;
    assertPositiveNumber(t: ExecutionContext, params: {
        name: string;
        labels?: Record<string, string>;
    }): void;
}
export declare class TestAdapter<T extends SettingsDefinitionMap = SettingsDefinitionMap> {
    api: FastifyInstance;
    adapter: Adapter<T>;
    metricsApi?: FastifyInstance | undefined;
    clock?: InstalledClock | undefined;
    mockCache?: MockCache;
    constructor(api: FastifyInstance, adapter: Adapter<T>, metricsApi?: FastifyInstance | undefined, clock?: InstalledClock | undefined, cache?: Cache);
    static startWithMockedCache<T extends SettingsDefinitionMap = SettingsDefinitionMap>(adapter: Adapter<T>, context: ExecutionContext<{
        clock?: InstalledClock;
        testAdapter: TestAdapter<T>;
    }>['context'], dependencies?: Partial<AdapterDependencies>): Promise<TestAdapter<T> & {
        mockCache: MockCache;
    }>;
    static start<T extends SettingsDefinitionMap = SettingsDefinitionMap>(adapter: Adapter<T>, context: ExecutionContext<{
        clock?: InstalledClock;
        testAdapter: TestAdapter<T>;
    }>['context'], dependencies?: Partial<AdapterDependencies>): Promise<TestAdapter<T>>;
    request(data?: object, headers?: Record<string, string>): Promise<import("light-my-request").Response>;
    startBackgroundExecuteThenGetResponse(t: ExecutionContext, params: {
        requestData: object;
        expectedResponse?: PartialAdapterResponse & {
            statusCode: number;
        };
        expectedCacheSize?: number;
    }): Promise<import("light-my-request").Response>;
    waitForCache(expectedSize?: number): Promise<void>;
    getMetrics(): Promise<TestMetrics>;
    getHealth(): Promise<import("light-my-request").Response>;
}
export declare function waitUntilResolved<T>(clock: InstalledClock, fn: () => Promise<T>): Promise<T>;
export declare function setEnvVariables(envVariables: NodeJS.ProcessEnv): void;
/**
 * Sets the mocked websocket instance in the provided provider class.
 * We need this here, because the tests will connect using their instance of WebSocketClassProvider;
 * fetching from this library to the \@chainlink/ea-bootstrap package would access _another_ instance
 * of the same constructor. Although it should be a singleton, dependencies are different so that
 * means that the static classes themselves are also different.
 *
 * @param provider - singleton WebSocketClassProvider
 */
export declare const mockWebSocketProvider: (provider: typeof WebSocketClassProvider) => void;
export declare function makeStub<T>(name: string, obj: T): T;
export declare const allowedUndefinedStubProps: string[];
