/**
 * Copyright 2022-2023, Optimizely
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { LogHandler } from '../../modules/logging';
import { OdpEvent } from './odp_event';
import { OdpConfig } from './odp_config';
import { IOdpEventApiManager } from './odp_event_api_manager';
import { IUserAgentParser } from './user_agent_parser';
/**
 * Event dispatcher's execution states
 */
export declare enum STATE {
    STOPPED = 0,
    RUNNING = 1,
    PROCESSING = 2
}
/**
 * Manager for persisting events to the Optimizely Data Platform (ODP)
 */
export interface IOdpEventManager {
    updateSettings(odpConfig: OdpConfig): void;
    start(): void;
    stop(): Promise<void>;
    registerVuid(vuid: string): void;
    identifyUser(userId?: string, vuid?: string): void;
    sendEvent(event: OdpEvent): void;
    flush(): void;
}
/**
 * Concrete implementation of a manager for persisting events to the Optimizely Data Platform
 */
export declare abstract class OdpEventManager implements IOdpEventManager {
    /**
     * Current state of the event processor
     */
    state: STATE;
    /**
     * Queue for holding all events to be eventually dispatched
     * @protected
     */
    protected queue: OdpEvent[];
    /**
     * Identifier of the currently running timeout so clearCurrentTimeout() can be called
     * @private
     */
    private timeoutId?;
    /**
     * ODP configuration settings for identifying the target API and segments
     * @private
     */
    private odpConfig;
    /**
     * REST API Manager used to send the events
     * @private
     */
    private readonly apiManager;
    /**
     * Handler for recording execution logs
     * @private
     */
    private readonly logger;
    /**
     * Maximum queue size
     * @protected
     */
    protected queueSize: number;
    /**
     * Maximum number of events to process at once. Ignored in browser context
     * @protected
     */
    protected batchSize: number;
    /**
     * Milliseconds between setTimeout() to process new batches. Ignored in browser context
     * @protected
     */
    protected flushInterval: number;
    /**
     * Type of execution context eg node, js, react
     * @private
     */
    private readonly clientEngine;
    /**
     * Version of the client being used
     * @private
     */
    private readonly clientVersion;
    /**
     * Version of the client being used
     * @private
     */
    private readonly userAgentParser?;
    /**
     * Information about the user agent
     * @private
     */
    private readonly userAgentData?;
    constructor({ odpConfig, apiManager, logger, clientEngine, clientVersion, queueSize, batchSize, flushInterval, userAgentParser, }: {
        odpConfig: OdpConfig;
        apiManager: IOdpEventApiManager;
        logger: LogHandler;
        clientEngine: string;
        clientVersion: string;
        queueSize?: number;
        batchSize?: number;
        flushInterval?: number;
        userAgentParser?: IUserAgentParser;
    });
    protected abstract initParams(batchSize: number | undefined, queueSize: number | undefined, flushInterval: number | undefined): void;
    /**
     * Update ODP configuration settings.
     * @param newConfig New configuration to apply
     */
    updateSettings(newConfig: OdpConfig): void;
    /**
     * Cleans up all pending events; occurs every time the ODP Config is updated.
     */
    flush(): void;
    /**
     * Start processing events in the queue
     */
    start(): void;
    /**
     * Drain the queue sending all remaining events in batches then stop processing
     */
    stop(): Promise<void>;
    /**
     * Register a new visitor user id (VUID) in ODP
     * @param vuid Visitor User ID to send
     */
    registerVuid(vuid: string): void;
    /**
     * Associate a full-stack userid with an established VUID
     * @param {string} userId   (Optional) Full-stack User ID
     * @param {string} vuid     (Optional) Visitor User ID
     */
    identifyUser(userId?: string, vuid?: string): void;
    /**
     * Send an event to ODP via dispatch queue
     * @param event ODP Event to forward
     */
    sendEvent(event: OdpEvent): void;
    /**
     * Add a new event to the main queue
     * @param event ODP Event to be queued
     * @private
     */
    private enqueue;
    protected abstract hasNecessaryIdentifiers(event: OdpEvent): boolean;
    /**
     * Process events in the main queue
     * @param shouldFlush Flush all events regardless of available queue event count
     * @private
     */
    private processQueue;
    /**
     * Clear the currently running timout
     * @private
     */
    private clearCurrentTimeout;
    /**
     * Start a new timeout
     * @private
     */
    private setNewTimeout;
    /**
     * Make a batch and send it to ODP
     * @private
     */
    private makeAndSend1Batch;
    /**
     * Check if main queue has any full/even batches available
     * @returns True if there are event batches available in the queue otherwise False
     * @private
     */
    private queueHasBatches;
    /**
     * Check if main queue has any items
     * @returns True if there are any events in the queue otherwise False
     * @private
     */
    private queueContainsItems;
    /**
     * Check if the ODP Configuration is ready and log if not.
     * Potentially clear queue if server-side
     * @returns True if the ODP configuration is ready otherwise False
     * @private
     */
    private isOdpConfigurationReady;
    protected abstract discardEventsIfNeeded(): void;
    /**
     * Add additional common data including an idempotent ID and execution context to event data
     * @param sourceData Existing event data to augment
     * @returns Augmented event data
     * @private
     */
    private augmentCommonData;
    protected getLogger(): LogHandler;
}
