import { EventEmitter } from 'node:events';
import { SinonSandbox, SinonStatic, SinonStub } from 'sinon';
import { AnyJson, JsonMap, Optional } from '@salesforce/ts-types';
import { ConfigContents } from './config/configStackTypes';
import { Connection } from './org/connection';
import { Logger } from './logger/logger';
import { SfError } from './sfError';
import { CometClient, CometSubscription, Message, StreamingExtension } from './status/streamingClient';
import { SandboxFields } from './org/org';
import { AuthFields } from './org/authInfo';
import { uniqid } from './util/uniqid';
export { uniqid };
export { SecureBuffer } from './crypto/secureBuffer';
/**
 * Different parts of the system that are mocked out. They can be restored for
 * individual tests. Test's stubs should always go on the DEFAULT which is exposed
 * on the TestContext.
 */
export type SandboxTypes = {
    DEFAULT: SinonSandbox;
    CRYPTO: SinonSandbox;
    CONFIG: SinonSandbox;
    PROJECT: SinonSandbox;
    CONNECTION: SinonSandbox;
    FS: SinonSandbox;
    ORGS: SinonSandbox;
};
/**
 * Different hooks into {@link ConfigFile} used for testing instead of doing file IO.
 */
export type ConfigStub = {
    /**
     * readFn A function that controls all aspect of {@link ConfigFile.read}. For example, it won't set the contents
     * unless explicitly done. Only use this if you know what you are doing. Use retrieveContents
     * instead.
     */
    readFn?: () => Promise<ConfigContents>;
    /**
     * A function that controls all aspects of {@link ConfigFile.write}. For example, it won't read the contents unless
     * explicitly done. Only use this if you know what you are doing. Use updateContents instead.
     */
    writeFn?: (contents?: AnyJson) => Promise<void>;
    /**
     * The contents that are used with @{link ConfigFile.readSync} and @{link ConfigFile.read}. If retrieveContents is set,
     * it will use that instead of @{link ConfigFile.read} but NOT @{link ConfigFile.readSync}. This will also contain the
     * new config when @{link ConfigFile.write} or @{link ConfigFile.writeSync} is called. This will persist through config instances,
     * such as {@link Alias.update} and {@link Alias.fetch}.
     */
    contents?: ConfigContents;
    /**
     * A function to conditionally read based on the config instance. The `this` value will be the config instance.
     */
    retrieveContents?: () => Promise<JsonMap>;
};
/**
 * Instantiate a @salesforce/core test context.
 */
export declare class TestContext {
    /**
     * The default sandbox is cleared out before each test run.
     *
     * **See** [sinon sandbox]{@link https://sinonjs.org/releases/v14/sandbox/}.
     */
    SANDBOX: SinonSandbox;
    /**
     * An object of different sandboxes. Used when
     * needing to restore parts of the system for customized testing.
     */
    SANDBOXES: SandboxTypes;
    /**
     * The test logger that is used when {@link Logger.child} is used anywhere. It uses memory logging.
     */
    TEST_LOGGER: Logger;
    /**
     * id A unique id for the test run.
     */
    id: string;
    /**
     * An object used in tests that interact with config files.
     */
    configStubs: {
        [configName: string]: Optional<ConfigStub>;
        AuthInfoConfig?: ConfigStub;
        Config?: ConfigStub;
        SfProjectJson?: ConfigStub;
        OrgUsersConfig?: ConfigStub;
    };
    /**
     * A record of stubs created during instantiation.
     */
    stubs: Record<string, SinonStub>;
    constructor(options?: {
        sinon?: SinonStatic;
        sandbox?: SinonSandbox;
        setup?: boolean;
    });
    /**
     * Generate unique string.
     */
    uniqid(): string;
    /**
     * A function used when resolving the local path. Calls localPathResolverSync by default.
     *
     * @param uid Unique id.
     */
    localPathRetriever(uid: string): Promise<string>;
    /**
     * A function used when resolving the local path.
     *
     * @param uid Unique id.
     */
    localPathRetrieverSync(uid: string): string;
    /**
     * A function used when resolving the global path. Calls globalPathResolverSync by default.
     *
     * @param uid Unique id.
     */
    globalPathRetriever(uid: string): Promise<string>;
    /**
     * A function used when resolving the global path.
     *
     * @param uid Unique id.
     */
    globalPathRetrieverSync(uid: string): string;
    /**
     * A function used for resolving paths. Calls localPathRetriever and globalPathRetriever.
     *
     * @param isGlobal `true` if the config is global.
     * @param uid user id.
     */
    rootPathRetriever(isGlobal: boolean, uid?: string): Promise<string>;
    /**
     * A function used for resolving paths. Calls localPathRetrieverSync and globalPathRetrieverSync.
     *
     * @param isGlobal `true` if the config is global.
     * @param uid user id.
     */
    rootPathRetrieverSync(isGlobal: boolean, uid?: string): string;
    /**
     * Used to mock http request to Salesforce.
     *
     * @param request An HttpRequest.
     * @param options Additional options.
     *
     * **See** {@link Connection.request}
     */
    fakeConnectionRequest(request: AnyJson, options?: AnyJson): Promise<AnyJson>;
    /**
     * Gets a config stub contents by name.
     *
     * @param name The name of the config.
     * @param group If the config supports groups.
     */
    getConfigStubContents(name: string, group?: string): ConfigContents;
    /**
     * Sets a config stub contents by name
     *
     * @param name The name of the config stub.
     * @param value The actual stub contents. The Mock data.
     */
    setConfigStubContents(name: string, value: ConfigContents): void;
    /**
     * Set stubs for working in the context of a SfProject
     */
    inProject(inProject?: boolean): void;
    /**
     * Stub salesforce org authorizations.
     */
    stubAuths(...orgs: MockTestOrgData[]): Promise<void>;
    /**
     * Stub salesforce user authorizations.
     *
     * @param users The users to stub.
     * The key is the username of the admin user and it must be included in the users array in order to obtain the orgId key for the remaining users.
     * The admin user is excluded from the users array.
     *
     */
    stubUsers(users: Record<string, MockTestOrgData[]>): void;
    /**
     * Stub salesforce sandbox authorizations.
     */
    stubSandboxes(...sandboxes: MockTestSandboxData[]): Promise<void>;
    /**
     * Stub the aliases in the global aliases config file.
     */
    stubAliases(aliases: Record<string, string>, group?: string): void;
    /**
     * Stub contents in the config file.
     */
    stubConfig(config: Record<string, string>): Promise<void>;
    restore(): void;
    init(): void;
    /**
     * Add beforeEach and afterEach hooks to init the stubs and restore them.
     * This is called automatically when the class is instantiated unless the setup option is set to false.
     */
    setup(): void;
}
/**
 * Instantiate a @salesforce/core test context. This is automatically created by `const $$ = testSetup()`
 * but is useful if you don't want to have a global stub of @salesforce/core and you want to isolate it to
 * a single describe.
 *
 * **Note:** Call `stubContext` in your beforeEach to have clean stubs of @salesforce/core every test run.
 *
 * @example
 * ```
 * const $$ = instantiateContext();
 *
 * beforeEach(() => {
 *   $$.init()
 * });
 *
 * afterEach(() => {
 *   $$.restore();
 * });
 * ```
 * @param sinon
 */
export declare const instantiateContext: (sinon?: SinonStatic) => TestContext;
/**
 * Stub a @salesforce/core test context. This will mock out logging to a file, config file reading and writing,
 * local and global path resolution, and http request using connection (soon)*.
 *
 * This is automatically stubbed in the global beforeEach created by
 * `const $$ = testSetup()` but is useful if you don't want to have a global stub of @salesforce/core and you
 * want to isolate it to a single describe.
 *
 * **Note:** Always call `restoreContext` in your afterEach.
 *
 * @example
 * ```
 * const $$ = instantiateContext();
 *
 * beforeEach(() => {
 *   $$.init()
 * });
 *
 * afterEach(() => {
 *   $$.restore();
 * });
 * ```
 * @param testContext
 */
export declare const stubContext: (testContext: TestContext) => Record<string, SinonStub>;
/**
 * Restore a @salesforce/core test context. This is automatically stubbed in the global beforeEach created by
 * `const $$ = testSetup()` but is useful if you don't want to have a global stub of @salesforce/core and you
 * want to isolate it to a single describe.
 *
 * @example
 * ```
 * const $$ = instantiateContext();
 *
 * beforeEach(() => {
 *   $$.init()
 * });
 *
 * afterEach(() => {
 *   $$.restore();
 * });
 * ```
 * @param testContext
 */
export declare const restoreContext: (testContext: TestContext) => void;
/**
 * A pre-canned error for try/catch testing.
 *
 * **See** {@link shouldThrow}
 */
export declare const unexpectedResult: SfError<AnyJson>;
/**
 * Use for this testing pattern:
 * ```
 *  try {
 *      await call()
 *      assert.fail("this should never happen");
 *  } catch (e) {
 *  ...
 *  }
 *
 *  Just do this
 *
 *  try {
 *      await shouldThrow(call()); // If this succeeds unexpectedResultError is thrown.
 *  } catch(e) {
 *  ...
 *  }
 * ```
 *
 * @param f The async function that is expected to throw.
 */
export declare function shouldThrow(f: Promise<unknown>, message?: string): Promise<never>;
/**
 * Use for this testing pattern:
 * ```
 *  try {
 *      call()
 *      assert.fail("this should never happen");
 *  } catch (e) {
 *  ...
 *  }
 *
 *  Just do this
 *
 *  try {
 *      shouldThrowSync(call); // If this succeeds unexpectedResultError is thrown.
 *  } catch(e) {
 *  ...
 *  }
 * ```
 *
 * @param f The function that is expected to throw.
 */
export declare function shouldThrowSync(f: () => unknown, message?: string): never;
/**
 * A helper to determine if a subscription will use callback or errorback.
 * Enable errback to simulate a subscription failure.
 */
export declare enum StreamingMockSubscriptionCall {
    CALLBACK = 0,
    ERRORBACK = 1
}
/**
 * Additional subscription options for the StreamingMock.
 */
export type StreamingMockCometSubscriptionOptions = {
    /**
     * Target URL.
     */
    url: string;
    /**
     * Simple id to associate with this instance.
     */
    id: string;
    /**
     * What is the subscription outcome a successful callback or an error?.
     */
    subscriptionCall: StreamingMockSubscriptionCall;
    /**
     * If it's an error that states what that error should be.
     */
    subscriptionErrbackError?: SfError;
    /**
     * A list of messages to playback for the client. One message per process tick.
     */
    messagePlaylist?: Message[];
};
/**
 * Simulates a comet subscription to a streaming channel.
 */
export declare class StreamingMockCometSubscription extends EventEmitter implements CometSubscription {
    static SUBSCRIPTION_COMPLETE: string;
    static SUBSCRIPTION_FAILED: string;
    private options;
    constructor(options: StreamingMockCometSubscriptionOptions);
    /**
     * Sets up a streaming subscription callback to occur after the setTimeout event loop phase.
     *
     * @param callback The function to invoke.
     */
    callback(callback: () => void): void;
    /**
     * Sets up a streaming subscription errback to occur after the setTimeout event loop phase.
     *
     * @param callback The function to invoke.
     */
    errback(callback: (error: Error) => void): void;
}
/**
 * Simulates a comet client. To the core streaming client this mocks the internal comet impl.
 * The uses setTimeout(0ms) event loop phase just so the client can simulate actual streaming without the response
 * latency.
 */
export declare class StreamingMockCometClient extends CometClient {
    private readonly options;
    /**
     * Constructor
     *
     * @param {StreamingMockCometSubscriptionOptions} options Extends the StreamingClient options.
     */
    constructor(options: StreamingMockCometSubscriptionOptions);
    /**
     * Fake addExtension. Does nothing.
     */
    addExtension(extension: StreamingExtension): void;
    /**
     * Fake disable. Does nothing.
     */
    disable(label: string): void;
    /**
     * Fake handshake that invoke callback after the setTimeout event phase.
     *
     * @param callback The function to invoke.
     */
    handshake(callback: () => void): void;
    /**
     * Fake setHeader. Does nothing,
     */
    setHeader(name: string, value: string): void;
    /**
     * Fake subscription that completed after the setTimout event phase.
     *
     * @param channel The streaming channel.
     * @param callback The function to invoke after the subscription completes.
     */
    subscribe(channel: string, callback: (message: Message) => void): CometSubscription;
    /**
     * Fake disconnect. Does Nothing.
     */
    disconnect(): Promise<void>;
}
type MockUserInfo = {
    Id: string;
    Username: string;
    LastName: string;
    Alias: string;
    Configs: string[] | undefined;
    TimeZoneSidKey: string;
    LocaleSidKey: string;
    EmailEncodingKey: string;
    ProfileId: string;
    LanguageLocaleKey: string;
    Email: string;
};
/**
 * Mock class for Salesforce Orgs.
 *
 * @example
 * ```
 * const testOrg = new MockTestOrgData();
 * await $$.stubAuths(testOrg)
 * ```
 */
export declare class MockTestOrgData {
    testId: string;
    aliases?: string[];
    configs?: string[];
    username: string;
    devHubUsername?: string;
    orgId: string;
    loginUrl: string;
    instanceUrl: string;
    clientId: string;
    clientSecret: string;
    authcode: string;
    accessToken: string;
    refreshToken: string | undefined;
    tracksSource: boolean | undefined;
    userId: string;
    redirectUri: string;
    isDevHub?: boolean;
    isScratchOrg?: boolean;
    isExpired?: boolean | 'unknown';
    password?: string;
    namespacePrefix?: string;
    constructor(id?: string, options?: {
        username: string;
    });
    /**
     * Add devhub username to properties.
     */
    createDevHubUsername(username: string): void;
    /**
     * Mark this org as a devhub.
     */
    makeDevHub(): void;
    /**
     * Returns a MockTestOrgData that represents a user created in the org.
     */
    createUser(user: string): MockTestOrgData;
    /**
     * Return mock user information based on this org.
     */
    getMockUserInfo(): MockUserInfo;
    /**
     * Return the auth config file contents.
     */
    getConfig(): Promise<AuthFields>;
    /**
     * Return the Connection for the org.
     */
    getConnection(): Promise<Connection>;
}
/**
 * Mock class for Salesforce Sandboxes.
 *
 * @example
 * ```
 * const testOrg = new MockTestSandboxData();
 * await $$.stubSandboxes(testOrg)
 * ```
 */
export declare class MockTestSandboxData {
    id: string;
    sandboxOrgId: string;
    prodOrgUsername: string;
    sandboxName?: string;
    username?: string;
    constructor(id?: string, options?: Partial<{
        prodOrgUsername: string;
        name: string;
        username: string;
    }>);
    /**
     * Return the auth config file contents.
     */
    getConfig(): Promise<SandboxFields>;
}
