import { StreamSfuClient } from '../StreamSfuClient';
import { StatsOptions } from '../gen/coordinator';
import { Publisher, Subscriber } from '../rtc';
import { Tracer } from './rtc';
import { ClientDetails, WebsocketReconnectStrategy } from '../gen/video/sfu/models/models';
import { CameraManager, MicrophoneManager } from '../devices';
import { CallState } from '../store';
export type SfuStatsReporterOptions = {
    options: StatsOptions;
    clientDetails: ClientDetails;
    subscriber: Subscriber;
    publisher?: Publisher;
    microphone: MicrophoneManager;
    camera: CameraManager;
    state: CallState;
    tracer: Tracer;
    unifiedSessionId: string;
};
export declare class SfuStatsReporter {
    private readonly logger;
    readonly options: StatsOptions;
    private readonly sfuClient;
    private readonly subscriber;
    private readonly publisher?;
    private readonly microphone;
    private readonly camera;
    private readonly state;
    private readonly tracer;
    private readonly unifiedSessionId;
    private intervalId;
    private timeoutId;
    private reportCount;
    private unsubscribeDevicePermissionsSubscription?;
    private unsubscribeListDevicesSubscription?;
    private readonly sdkName;
    private readonly sdkVersion;
    private readonly webRTCVersion;
    private readonly inputDevices;
    private readonly statsConcurrencyTag;
    private isStopped;
    constructor(sfuClient: StreamSfuClient, { options, clientDetails, subscriber, publisher, microphone, camera, state, tracer, unifiedSessionId, }: SfuStatsReporterOptions);
    private observeDevice;
    sendConnectionTime: (connectionTimeSeconds: number) => void;
    sendReconnectionTime: (strategy: WebsocketReconnectStrategy, timeSeconds: number) => void;
    private sendTelemetryData;
    /**
     * Samples both peer connections. Each `StatsTracer.takeSample()` is serialized
     * internally, so this is safe even if it overlaps another sample (e.g. the
     * connection-state-change handler). Kept separate from `send()` so an
     * explicit flush can capture the sample from live peer connections before
     * they are disposed, without waiting for an in-flight send.
     */
    private sample;
    private send;
    /**
     * Samples and sends one report. Used by the scheduler and the telemetry path.
     * Bails if the reporter has been stopped so it never samples disposed peer
     * connections.
     */
    private run;
    private scheduleNextReport;
    start: () => void;
    stop: () => void;
    /**
     * Explicit/final flush (leave, migration, re-init). Time-boxes the sampling
     * step and swallows its failures, so a slow or failing `getStats()` on a
     * degraded or closing peer connection can never block or reject call teardown
     * or reconnect setup. On a successful sample it fires the send best-effort;
     * the returned promise resolves once the sample is taken (or the time-box
     * elapses / sampling fails), never when the sending completes. No-op once the
     * reporter has been stopped.
     */
    flush: () => Promise<void>;
    /**
     * Flush entry for the periodic scheduler. Skips when the reporter is stopped
     * or a send is already in flight so ticks can't pile up under slow sends (the
     * next sample's delta spans the skipped interval).
     */
    private scheduledFlush;
}
