/*
 * 1DS JS SDK Post Channel, 4.0.6
 * Copyright (c) Microsoft and contributors. All rights reserved.
 *
 * Microsoft Application Insights Team
 * https://github.com/microsoft/ApplicationInsights-JS#readme
 */

declare namespace oneDS {
    import { BaseTelemetryPlugin } from '@microsoft/1ds-core-js';
    import { IAppInsightsCore } from '@microsoft/1ds-core-js';
    import { IChannelControls } from '@microsoft/1ds-core-js';
    import { IDiagnosticLogger } from '@microsoft/1ds-core-js';
    import { IExtendedConfiguration } from '@microsoft/1ds-core-js';
    import { IPayloadData } from '@microsoft/1ds-core-js';
    import { IPlugin } from '@microsoft/1ds-core-js';
    import { IProcessTelemetryContext } from '@microsoft/1ds-core-js';
    import { IPromise } from '@nevware21/ts-async';
    import { ITelemetryItem } from '@microsoft/1ds-core-js';
    import { ITelemetryPlugin } from '@microsoft/1ds-core-js';
    import { IUnloadHook } from '@microsoft/1ds-core-js';
    import { IValueSanitizer } from '@microsoft/1ds-core-js';
    import { IXHROverride } from '@microsoft/1ds-core-js';
    import { OnCompleteCallback } from '@microsoft/1ds-core-js';
    import { SendPOSTFunction } from '@microsoft/1ds-core-js';
    import { SendRequestReason } from '@microsoft/1ds-core-js';

    /**
     * Best Effort. RealTime Latency events are sent every 9 sec and
     * Normal Latency events are sent every 18 sec.
     */
    const BE_PROFILE = "BEST_EFFORT";

    /**
     * The IChannelConfiguration interface holds the configuration details passed to Post module.
     */
    interface IChannelConfiguration {
        /**
         * [Optional] The number of events that can be kept in memory before the SDK starts to drop events. By default, this is 10,000.
         */
        eventsLimitInMem?: number;
        /**
         * [Optional] Sets the maximum number of immediate latency events that will be cached in memory before the SDK starts to drop other
         * immediate events only, does not drop normal and real time latency events as immediate events have their own internal queue. Under
         * normal situations immediate events are scheduled to be sent in the next Javascript execution cycle, so the typically number of
         * immediate events is small (~1), the only time more than one event may be present is when the channel is paused or immediate send
         * is disabled (via manual transmit profile). By default max number of events is 500 and the default transmit time is 0ms.
         */
        immediateEventLimit?: number;
        /**
         * [Optional] If defined, when the number of queued events reaches or exceeded this limit this will cause the queue to be immediately
         * flushed rather than waiting for the normal timers. Defaults to undefined.
         */
        autoFlushEventsLimit?: number;
        /**
         * [Optional] If defined allows you to disable the auto batch (iKey set of requests) flushing logic. This is in addition to the
         * default transmission profile timers, autoFlushEventsLimit and eventsLimitInMem config values.
         */
        disableAutoBatchFlushLimit?: boolean;
        /**
         * [Optional] The HTTP override that should be used to send requests, as an IXHROverride object.
         * By default during the unload of a page or if the event specifies that it wants to use sendBeacon() or sync fetch (with keep-alive),
         * this override will NOT be called. You can now change this behavior by enabling the 'alwaysUseXhrOverride' configuration value.
         * The payload data (first argument) now also includes any configured 'timeout' (defaults to undefined) and whether you should avoid
         * creating any synchronous XHR requests 'disableXhrSync' (defaults to false/undefined)
         */
        httpXHROverride?: IXHROverride;
        /**
         * Override for Instrumentation key
         */
        overrideInstrumentationKey?: string;
        /**
         * Override for Endpoint where telemetry data is sent
         */
        overrideEndpointUrl?: string;
        /**
         * The master off switch.  Do not send any data if set to TRUE
         */
        disableTelemetry?: boolean;
        /**
         * MC1 and MS0 cookies will not be returned from Collector endpoint.
         */
        ignoreMc1Ms0CookieProcessing?: boolean;
        /**
         * Override for setTimeout
         */
        setTimeoutOverride?: typeof setTimeout;
        /**
         * Override for clearTimeout
         */
        clearTimeoutOverride?: typeof clearTimeout;
        /**
         * [Optional] POST channel preprocessing function. Can be used to gzip the payload before transmission and to set the appropriate
         * Content-Encoding header. The preprocessor is explicitly not called during teardown when using the sendBeacon() API.
         */
        payloadPreprocessor?: PayloadPreprocessorFunction;
        /**
         * [Optional] POST channel listener function, used for enabling logging or reporting (RemoteDDVChannel) of the payload that is being sent.
         */
        payloadListener?: PayloadListenerFunction;
        /**
         * [Optional] By default additional timing metrics details are added to each event after they are sent to allow you to review how long it took
         * to create serialized request. As not all implementations require this level of detail and it's now possible to get the same metrics via
         * the IPerfManager and IPerfEvent we are enabling these details to be disabled. Default value is false to retain the previous behavior,
         * if you are not using these metrics and performance is a concern then it is recommended to set this value to true.
         */
        disableEventTimings?: boolean;
        /**
         * [Optional] The value sanitizer to use while constructing the envelope.
         */
        valueSanitizer?: IValueSanitizer;
        /**
         * [Optional] During serialization, when an object is identified, should the object be serialized by JSON.stringify(theObject); (when true) otherwise by theObject.toString().
         * Defaults to false
         */
        stringifyObjects?: boolean;
        /**
         * [Optional] Enables support for objects with compound keys which indirectly represent an object where the "key" of the object contains a "." as part of it's name.
         * @example
         * ```typescript
         * event: { "somedata.embeddedvalue": 123 }
         * ```
         */
        enableCompoundKey?: boolean;
        /**
         * [Optional] Switch to disable the v8 optimizeObject() calls used to provide better serialization performance. Defaults to false.
         */
        disableOptimizeObj?: boolean;
        /**
         * [Optional] By default a "Cache-Control" header will be added to the outbound payloads with the value "no-cache, no-store", this is to
         * avoid instances where Chrome can "Stall" requests which use the same outbound URL.
         */
        /**
         * [Optional] Either an array or single value identifying the requested TransportType type that should be used.
         * This is used during initialization to identify the requested send transport, it will be ignored if a httpXHROverride is provided.
         */
        transports?: number | number[];
        /**
         * [Optional] Either an array or single value identifying the requested TransportType type(s) that should be used during unload or events
         * marked as sendBeacon. This is used during initialization to identify the requested send transport, it will be ignored if a httpXHROverride
         * is provided and alwaysUseXhrOverride is true.
         */
        unloadTransports?: number | number[];
        /**
         * [Optional] A flag to enable or disable the usage of the sendBeacon() API (if available). If running on ReactNative this defaults
         * to `false` for all other cases it defaults to `true`.
         */
        useSendBeacon?: boolean;
        /**
         * [Optional] A flag to disable the usage of the [fetch with keep-alive](https://javascript.info/fetch-api#keepalive) support.
         */
        disableFetchKeepAlive?: boolean;
        /**
         * [Optional] Avoid adding request headers to the outgoing request that would cause a pre-flight (OPTIONS) request to be sent for each request.
         * This currently defaults to true but will be changed once the collector handles additional settings to allow the browser to better cache any
         * previous OPTIONS response, at which point some of the current dynamic values sent on the query string will be moved to a header.
         */
        avoidOptions?: boolean;
        /**
         * [Optional] Specify a timeout (in ms) to apply to requests when sending requests using XHR, XDR or fetch requests. Defaults to undefined
         * and therefore the runtime defaults (normally zero for browser environments)
         */
        xhrTimeout?: number;
        /**
         * [Optional] When using Xhr for sending requests disable sending as synchronous during unload or synchronous flush.
         * You should enable this feature for IE (when there is no sendBeacon() or fetch (with keep-alive)) and you have clients
         * that end up blocking the UI during page unloading. This will cause ALL XHR requests to be sent asynchronously which
         * during page unload may result in the lose of telemetry.
         */
        disableXhrSync?: boolean;
        /**
         * [Optional] By default during unload (or when you specify to use sendBeacon() or sync fetch (with keep-alive) for an event) the SDK
         * ignores any provided httpXhrOverride and attempts to use sendBeacon() or fetch(with keep-alive) when they are available.
         * When this configuration option is true any provided httpXhrOverride will always be used, so any provided httpXhrOverride will
         * also need to "handle" the synchronous unload scenario.
         */
        alwaysUseXhrOverride?: boolean;
        /**
         * [Optional] Identifies the number of times any single event will be retried if it receives a failed (retirable) response, this
         * causes the event to be internally "requeued" and resent in the next batch. As each normal batched send request is retried at
         * least once before starting to increase the internal backoff send interval, normally batched events will generally be attempted
         * the next nearest even number of times. This means that the total number of actual send attempts will almost always be even
         * (setting to 5 will cause 6 requests), unless using manual synchronous flushing (calling flush(false)) which is not subject to
         * request level retry attempts.
         * Defaults to 6 times.
         */
        maxEventRetryAttempts?: number;
        /**
         * [Optional] Identifies the number of times any single event will be retried if it receives a failed (retriable) response as part
         * of processing / flushing events once a page unload state has been detected, this causes the event to be internally "requeued"
         * and resent in the next batch, which during page unload. Unlike the normal batching process, send requests are never retried,
         * so the value listed here is always the maximum number of attempts for any single event.
         * Defaults to 2 times.
         * Notes:
         * The SDK by default will use the sendBeacon() API if it exists which is treated as a fire and forget successful response, so for
         * environments that support or supply this API the events won't be retried (because they will be deeded to be successfully sent).
         * When an environment (IE) doesn't support sendBeacon(), this will cause multiple synchronous (by default) XMLHttpRequests to be sent,
         * which will block the UI until a response is received. You can disable ALL synchronous XHR requests by setting the 'disableXhrSync'
         * configuration setting and/or changing this value to 0 or 1.
         */
        maxUnloadEventRetryAttempts?: number;
        /**
         * [Optional] flag to indicate whether the sendBeacon and fetch (with keep-alive flag) should add the "NoResponseBody" query string
         * value to indicate that the server should return a 204 for successful requests. Defaults to true
         */
        addNoResponse?: boolean;
    }

    
    /**
     * Post channel interface
     */
    interface IPostChannel extends ITelemetryPlugin {
        /**
         * Diagnostic logger
         */
        diagLog: (itemCtx?: IProcessTelemetryContext) => IDiagnosticLogger;
        /**
         * Override for setTimeout
         */
        _setTimeoutOverride?: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => any;
        /**
         * Backs off transmission. This exponentially increases all the timers.
         */
        _backOffTransmission(): void;
        /**
         * Clears back off for transmission.
         */
        _clearBackOff(): void;
        /**
         * Add handler to be executed with request response text.
         */
        addResponseHandler(responseHandler: (responseText: string) => void): IUnloadHook;
    }

    
    /**
     * Near Real Time profile. RealTime Latency events are sent every 3 sec and
     * Normal Latency events are sent every 6 sec.
     */
    const NRT_PROFILE = "NEAR_REAL_TIME";

    
    /**
     * Defines the function signature of a payload listener, which is called after the payload has been sent to the server. The listener is passed
     * both the initial payload object and any altered (modified) payload from a preprocessor so it can determine what payload it may want to log or send.
     * Used by the Remove DDV extension to listen to server send events.
     * @param orgPayload - The initially constructed payload object
     * @param sendPayload - The alternative (possibly modified by a preprocessor) payload
     * @param isSync - A boolean flag indicating whether this request was initiated as part of a sync response (unload / flush request), this is for informative only.
     * @param isBeaconSend - A boolean flag indicating whether the payload was sent using the navigator.sendBeacon() API.
     */
    type PayloadListenerFunction = (orgPayload: IPayloadData, sendPayload?: IPayloadData, isSync?: boolean, isBeaconSend?: boolean) => void;

    /**
     * Defines the function signature for the Payload Preprocessor.
     * @param payload - The Initial constructed payload that if not modified should be passed onto the callback function.
     * @param callback - The preprocessor MUST call the callback function to ensure that the events are sent to the server, failing to call WILL result in dropped events.
     * The modifiedBuffer argument can be either the original payload or may be modified by performing GZipping of the payload and adding the content header.
     * @param isSync - A boolean flag indicating whether this request was initiated as part of a sync response (unload / flush request), this is for informative only.
     * e.g the preprocessor may wish to not perform any GZip operations if the request was a sync request which is normally called as part of an unload request.
     */
    type PayloadPreprocessorFunction = (payload: IPayloadData, callback: (modifiedBuffer: IPayloadData) => void, isSync?: boolean) => void;

    /**
     * Class that manages adding events to inbound queues and batching of events
     * into requests.
     * @group Classes
     * @group Entrypoint
     */
    class PostChannel extends BaseTelemetryPlugin implements IChannelControls, IPostChannel {
        identifier: string;
        priority: number;
        version: string;
        constructor();
        /**
         * Start the queue manager to batch and send events via post.
         * @param config - The core configuration.
         */
        initialize(coreConfig: IExtendedConfiguration, core: IAppInsightsCore, extensions: IPlugin[]): void;
        /**
         * Add an event to the appropriate inbound queue based on its latency.
         * @param ev - The event to be added to the queue.
         * @param itemCtx - This is the context for the current request, ITelemetryPlugin instances
         * can optionally use this to access the current core instance or define / pass additional information
         * to later plugins (vs appending items to the telemetry item)
         */
        processTelemetry(ev: ITelemetryItem, itemCtx?: IProcessTelemetryContext): void;
        /**
         * Sets the event queue limits at runtime (after initialization), if the number of queued events is greater than the
         * eventLimit or autoFlushLimit then a flush() operation will be scheduled.
         * @param eventLimit The number of events that can be kept in memory before the SDK starts to drop events. If the value passed is less than or
         * equal to zero the value will be reset to the default (10,000).
         * @param autoFlushLimit When defined, once this number of events has been queued the system perform a flush() to send the queued events
         * without waiting for the normal schedule timers. Passing undefined, null or a value less than or equal to zero will disable the auto flush.
         */
        setEventQueueLimits(eventLimit: number, autoFlushLimit?: number): void;
        /**
         * Pause the transmission of any requests
         */
        pause(): void;
        /**
         * Resumes transmission of events.
         */
        resume(): void;
        /**
         * Add handler to be executed with request response text.
         */
        addResponseHandler(responseHanlder: (responseText: string) => void): IUnloadHook;
        /**
         * Flush to send data immediately; channel should default to sending data asynchronously. If executing asynchronously (the default) and
         * you DO NOT pass a callback function then a [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html)
         * will be returned which will resolve once the flush is complete. The actual implementation of the `IPromise`
         * will be a native Promise (if supported) or the default as supplied by [ts-async library](https://github.com/nevware21/ts-async)
         * @param async - send data asynchronously when true
         * @param callBack - if specified, notify caller when send is complete, the channel should return true to indicate to the caller that it will be called.
         * If the caller doesn't return true the caller should assume that it may never be called.
         * @param sendReason - specify the reason that you are calling "flush" defaults to ManualFlush (1) if not specified
         * @returns - If a callback is provided `true` to indicate that callback will be called after the flush is complete otherwise the caller
         * should assume that any provided callback will never be called, Nothing or if occurring asynchronously a
         * [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html) which will be resolved once the unload is complete,
         * the [IPromise](https://nevware21.github.io/ts-async/typedoc/interfaces/IPromise.html) will only be returned when no callback is provided
         * and async is true.
         */
        flush(async?: boolean, callBack?: (flushComplete?: boolean) => void, sendReason?: SendRequestReason): boolean | void | IPromise<boolean>;
        /**
         * Set AuthMsaDeviceTicket header
         * @param ticket - Ticket value.
         */
        setMsaAuthTicket(ticket: string): void;
        /**
         * Check if there are any events waiting to be scheduled for sending.
         * @returns True if there are events, false otherwise.
         */
        hasEvents(): boolean;
        /**
         * Load custom transmission profiles. Each profile should have timers for real time, and normal and can
         * optionally specify the immediate latency time in ms (defaults to 0 when not defined). Each profile should
         * make sure that a each normal latency timer is a multiple of the real-time latency and the immediate
         * is smaller than the real-time.
         * Setting the timer value to -1 means that the events for that latency will not be scheduled to be sent.
         * Note that once a latency has been set to not send, all latencies below it will also not be sent. The
         * timers should be in the form of [normal, high, [immediate]].
         * e.g Custom:
         * [10,5] - Sets the normal latency time to 10 seconds and real-time to 5 seconds; Immediate will default to 0ms
         * [10,5,1] - Sets the normal latency time to 10 seconds and real-time to 5 seconds; Immediate will default to 1ms
         * [10,5,0] - Sets the normal latency time to 10 seconds and real-time to 5 seconds; Immediate will default to 0ms
         * [10,5,-1] - Sets the normal latency time to 10 seconds and real-time to 5 seconds; Immediate events will not be
         * scheduled on their own and but they will be included with real-time or normal events as the first events in a batch.
         * This also removes any previously loaded custom profiles.
         * @param profiles - A dictionary containing the transmit profiles.
         */
        _loadTransmitProfiles(profiles: {
            [profileName: string]: number[];
        }): void;
        /**
         * Set the transmit profile to be used. This will change the transmission timers
         * based on the transmit profile.
         * @param profileName - The name of the transmit profile to be used.
         */
        _setTransmitProfile(profileName: string): void;
        /**
         * Backs off transmission. This exponentially increases all the timers.
         */
        _backOffTransmission(): void;
        /**
         * Clears backoff for transmission.
         */
        _clearBackOff(): void;
    }

    /**
     * Real Time profile (default profile). RealTime Latency events are sent every 1 sec and
     * Normal Latency events are sent every 2 sec.
     */
    const RT_PROFILE = "REAL_TIME";

    
    
}