import { Logger } from '@o3r/core';
import { Observable } from 'rxjs';

/**
 * Shared interface with the A/B testing provider
 */
interface AbTestBridgeInterface<T> {
    /**
     * Start an AB testing experiment
     */
    start(experiments: T | T[]): void;
    /**
     * Stop an AB testing experiment
     */
    stop(experiments?: T | T[]): void;
}
/**
 * Configure the A/B testing script interfaces with the application
 */
interface AbTestBridgeConfig {
    /**
     * Reference to communicate with the bridge from the window
     * @default 'abTestBridge'
     */
    bridgeName: string;
    /**
     * Debug logger
     * @default console
     */
    logger: Logger;
    /**
     * Event a third party can subscribe to before starting the communication with the bridge
     * @default 'ab-test-ready'
     */
    readyEventName: string;
}
/**
 * Bridge between the application and a third party A/B testing provider.
 * Exposes a start and stop methods to allow the external script to set the list of experiments to run over the
 * application.
 *
 * Share the resulting list of experiments with the rest of the application via an observable.
 */
declare class AbTestBridge<T> implements AbTestBridgeInterface<T> {
    private readonly isExperimentEqual;
    /**
     * Behaviour subject to control the experiments via the exposed interface
     */
    private readonly experimentSubject$;
    /**
     * Options to configure the communication between the AB Testing bridge and third parties
     */
    private readonly options;
    /**
     * Observable with the list of AB testing experiments currently applied
     */
    experiments$: Observable<T[]>;
    /**
     * AbTestBridge constructor
     * @param isExperimentEqual check two different experiments match to identify an experiment to start or to stop
     * @param options configure the communication with the A/B testing third party provider
     */
    constructor(isExperimentEqual: (value1?: T, value2?: T) => boolean, options?: Partial<AbTestBridgeConfig>);
    /**
     * Use configured logger to log AB testing related information
     * @param args
     */
    private log;
    /**
     * @inheritDoc
     */
    start(experiments: T | T[]): void;
    /**
     * @inheritDoc
     */
    stop(experiments?: T | T[]): void;
}

/**
 * Represents messages exchanged between host and iFrame.
 */
interface IframeMessage {
    /**
     * String used to identify the type of action to perform.
     */
    action: string;
    /**
     * The version of the action, to allow for backward and forward compatibility.
     */
    version: string;
    /**
     * Payload of the message.
     */
    data?: unknown;
}
interface InternalIframeMessage extends IframeMessage {
    /**
     * The ID associated to the channel Host <-> iFrame
     */
    channelId: string;
    /**
     * ID used to handle messages that expect a response from the other party.
     * No used for unidirectional messages.
     */
    id?: string;
}
/**
 * Options that can be passed to configure an IFrameBridge
 */
interface IFrameBridgeOptions {
    /**
     * Number of times the Host will try to handshake with the iFrame before failing.
     */
    handshakeTries: number;
    /**
     * For a given handshake try, how long will the host wait for an answer before considering
     * that the try failed.
     */
    handshakeTimeout: number;
    /**
     * When sending a message that expects a response, how long should the Bridge wait before
     * considering there will be answer.
     */
    messageWithResponseTimeout: number;
}

/**
 * Bridge that exposes an easy abstraction layer to communicate between a Host and an IFrame using the
 * postMessage API.
 */
declare class IframeBridge {
    private readonly child;
    /** ID used to ensure that the Bridge only processes messages meant for this instance, since postMessage is global to the window. */
    private readonly channelId;
    /** Observable that emits all the messages received from the IFrame. */
    private readonly internalMessages$;
    /** Promise that will resolve once the handshake has been completed, undefined if it's already done. */
    private readonly handshakePromise?;
    /** Options to configure the behaviour of the Bridge. */
    private readonly options;
    /**
     * Observable that emits all the messages received from the IFrame and that are
     * not a direct response to a request.
     */
    readonly messages$: Observable<InternalIframeMessage>;
    constructor(parent: Window, child: HTMLIFrameElement, options?: Partial<IFrameBridgeOptions>);
    private handshake;
    private _sendMessage;
    private _sendMessageAndWaitForResponse;
    /**
     * Method to send a message to the script run in the iframe
     * @param message message object
     * @param messageId message identifier
     */
    sendMessage(message: IframeMessage, messageId?: string): Promise<void>;
    /**
     * Method to send a message to the script run in the iframe and wait for an answer
     * @param message
     * @param timeoutMilliseconds
     */
    sendMessageAndWaitForResponse(message: IframeMessage, timeoutMilliseconds?: number): Promise<InternalIframeMessage>;
}

/**
 * Default options for an IFrameBridge
 */
declare const IFRAME_BRIDGE_DEFAULT_OPTIONS: Readonly<IFrameBridgeOptions>;
/**
 * Verifies if a message respects the format expected by an IFrameBridge
 * @param message
 */
declare function isSupportedMessage(message: any): message is InternalIframeMessage;
/**
 * Generates the html content of an iframe
 * @param scriptUrl script to be executed inside the iframe
 * @param additionalHeader custom html headers stringified
 */
declare function generateIFrameContent(scriptUrl: string, additionalHeader?: string): string;

export { AbTestBridge, IFRAME_BRIDGE_DEFAULT_OPTIONS, IframeBridge, generateIFrameContent, isSupportedMessage };
export type { AbTestBridgeConfig, AbTestBridgeInterface, IFrameBridgeOptions, IframeMessage, InternalIframeMessage };
//# sourceMappingURL=o3r-third-party.d.ts.map
