import { FormatInitializationMetadata, MediaHeader, NextRequestPolicy, ReloadPlaybackContext, SabrContextUpdate, StreamProtectionStatus, type BufferedRange, type ClientInfo } from '../utils/Protos.js';
import type { SabrPlaybackOptions, SabrStreamConfig } from '../types/sabrStreamTypes.js';
import type { SabrFormat } from '../types/shared.js';
import { EventEmitterLike } from '../utils/index.js';
export interface InitializedFormat {
    formatInitializationMetadata: FormatInitializationMetadata;
    downloadedSegments: Map<number, Segment>;
    lastMediaHeaders: MediaHeader[];
}
export interface SabrStreamState {
    durationMs: number;
    requestNumber: number;
    playerTimeMs: number;
    activeSabrContexts: number[];
    sabrContextUpdates: Array<[number, SabrContextUpdate]>;
    formatToDiscard?: string;
    cachedBufferedRanges: BufferedRange[];
    nextRequestPolicy?: NextRequestPolicy;
    initializedFormats: Array<{
        formatKey: string;
        formatInitializationMetadata: FormatInitializationMetadata;
        downloadedSegments: Array<[number, Segment]>;
        lastMediaHeaders: MediaHeader[];
    }>;
}
interface SelectedFormats {
    videoFormat: SabrFormat;
    audioFormat: SabrFormat;
}
interface Segment {
    formatIdKey: string;
    segmentNumber: number;
    durationMs?: string;
    mediaHeader: MediaHeader;
    bufferedChunks: Uint8Array[];
}
/**
 * Manages the download and processing of YouTube's Server-Adaptive Bitrate (SABR) streams.
 *
 * This class handles the entire lifecycle of a SABR stream:
 * - Selecting appropriate video and audio formats.
 * - Making network requests to fetch media segments.
 * - Processing UMP parts in real-time.
 * - Handling server-side directives like redirects, context updates, and backoff policies.
 * - Emitting events for key stream updates, such as format initialization and errors.
 * - Providing separate `ReadableStream` instances for video and audio data.
 */
export declare class SabrStream extends EventEmitterLike {
    private readonly logger;
    private readonly fetchFunction;
    private readonly formatIds;
    private readonly videoStream;
    private readonly audioStream;
    private readonly umpPartHandlers;
    private serverAbrStreamingUrl?;
    private videoPlaybackUstreamerConfig?;
    private clientInfo?;
    private poToken?;
    private nextRequestPolicy?;
    private streamProtectionStatus?;
    private sabrContexts;
    private activeSabrContextTypes;
    private initializedFormatsMap;
    private abortController?;
    private partialSegmentQueue;
    private requestNumber;
    private durationMs;
    private cachedBufferedRanges;
    private formatToDiscard?;
    private mediaHeadersProcessed;
    private mainFormat?;
    private _errored;
    private _aborted;
    private progressTracker;
    private videoController?;
    private audioController?;
    /**
     * Fired when the server sends initialization metadata for a media format.
     * @event
     */
    on(event: 'formatInitialization', listener: (initializedFormat: InitializedFormat) => void): void;
    /**
     * Fired when the server provides an update on the stream's content protection status.
     * @event
     */
    on(event: 'streamProtectionStatusUpdate', listener: (data: StreamProtectionStatus) => void): void;
    /**
     * Fired when the server directs the client to reload the player, usually indicating the current session is invalid.
     * @event
     */
    on(event: 'reloadPlayerResponse', listener: (reloadPlaybackContext: ReloadPlaybackContext) => void): void;
    /**
     * Fired when the entire stream has been successfully downloaded.
     * @event
     */
    on(event: 'finish', listener: () => void): void;
    /**
     * Fired when the download process is manually aborted via the `abort()` method.
     * @event
     */
    on(event: 'abort', listener: () => void): void;
    once(event: 'formatInitialization', listener: (initializedFormat: InitializedFormat) => void): void;
    once(event: 'streamProtectionStatusUpdate', listener: (data: StreamProtectionStatus) => void): void;
    once(event: 'reloadPlayerResponse', listener: (reloadPlaybackContext: ReloadPlaybackContext) => void): void;
    once(event: 'finish', listener: () => void): void;
    once(event: 'abort', listener: () => void): void;
    constructor(config?: SabrStreamConfig);
    /**
     * Sets Proof of Origin (PO) token.
     * @param poToken - The base64-encoded token string.
     */
    setPoToken(poToken: string): void;
    /**
     * Sets the available server ABR formats.
     * @param formats - An array of available SabrFormat objects.
     */
    setServerAbrFormats(formats: SabrFormat[]): void;
    /**
     * Sets the total duration of the stream in milliseconds.
     * This is optional as duration is often determined automatically from format metadata.
     * @param durationMs - The duration in milliseconds.
     */
    setDurationMs(durationMs: number): void;
    /**
     * Sets the server ABR streaming URL for media requests.
     * @param url - The streaming URL.
     */
    setStreamingURL(url: string): void;
    /**
     * Sets the Ustreamer configuration string.
     * @param config - The Ustreamer configuration.
     */
    setUstreamerConfig(config: string): void;
    /**
     * Sets the client information used in SABR requests.
     * @param clientInfo - The client information object.
     */
    setClientInfo(clientInfo: ClientInfo): void;
    /**
     * Aborts the download process, closing all streams and cleaning up resources.
     * Emits an 'abort' event.
     */
    abort(): void;
    /**
     * Returns a serializable state object that can be used to restore the stream later.
     * @throws {Error} If the main format is not initialized.
     * @returns The current state of the stream.
     */
    getState(): SabrStreamState;
    /**
     * Initiates the streaming process for the selected formats.
     * @param options - Playback options, including format preferences and initial state.
     * @throws {Error} If no suitable formats are found or streaming fails.
     * @returns A promise that resolves with the video/audio streams and selected formats.
     */
    start(options: SabrPlaybackOptions): Promise<{
        videoStream: ReadableStream<Uint8Array>;
        audioStream: ReadableStream<Uint8Array>;
        selectedFormats: SelectedFormats;
    }>;
    /**
     * Sets up and manages the main streaming loop.
     * @param videoFormat - The selected video format.
     * @param audioFormat - The selected audio format.
     * @param options - Playback options.
     * @private
     */
    private setupStreamingProcess;
    /**
     * Restores the stream state from a previously saved state object.
     * @param videoFormat - The selected video format.
     * @param audioFormat - The selected audio format.
     * @param state - The saved state object.
     * @returns `true` if the state was restored successfully, `false` otherwise.
     * @private
     */
    private restoreState;
    /**
     * Checks if the download has stalled by tracking progress over time.
     * @param options - Configuration for stall detection.
     * @returns An object indicating whether the stream should stop and if it is stalled.
     * @throws {Error} If the maximum number of consecutive stalls is reached.
     * @private
     */
    private checkForStall;
    /**
     * Selects the best video and audio formats based on provided options.
     * @param options - Format selection options and quality preferences.
     * @throws {Error} If no suitable formats are found or the duration is invalid.
     * @returns The selected video and audio formats.
     * @private
     */
    private selectFormats;
    /**
     * Fetches and processes media segments from the server for the current ABR state.
     * @param abrState - The current client adaptive bitrate state.
     * @param selectedAudioFormat - The selected audio format.
     * @param selectedVideoFormat - The selected video format.
     * @throws {Error} If the server returns an error or no valid data.
     * @private
     */
    private fetchAndProcessSegments;
    /**
     * Constructs an array of `BufferedRange` objects from initialized formats.
     * @param initializedVideoFormat - The initialized video format, if available.
     * @param initializedAudioFormat - The initialized audio format, if available.
     * @returns An array of `BufferedRange` objects.
     * @private
     */
    private buildBufferedRanges;
    /**
     * Builds the protobuf request body for a `VideoPlaybackAbrRequest`.
     * @param abrState - The current client adaptive bitrate state.
     * @param selectedAudioFormat - The selected audio format.
     * @param selectedVideoFormat - The selected video format.
     * @returns The encoded request body as a `Uint8Array`.
     * @throws {Error} If required configuration (ustreamer config, client info) is missing.
     * @private
     */
    private buildRequestBody;
    /**
     * Prepares SABR context data for the request body.
     * @returns An object containing active and unsent SABR contexts.
     * @private
     */
    private prepareSabrContexts;
    /**
     * Prepares format selections and buffered ranges for the request body.
     * @param formats - An array of formats to process.
     * @param currentBufferedRanges - The current buffered ranges to update.
     * @returns An object with selected format IDs and updated buffered ranges.
     * @private
     */
    private prepareFormatSelections;
    /**
     * Executes a streaming POST request to the server.
     * @param body - The request body payload.
     * @returns A `Promise` that resolves with the server `Response`.
     * @throws {Error} If the server ABR streaming URL is not configured or the request fails.
     * @private
     */
    private makeStreamingRequest;
    /**
     * Reads the response body as a stream and processes each UMP part.
     * @param response - The server response to process.
     * @returns A promise that resolves to an array of processed UMP part types.
     * @throws {Error} If the response is invalid, empty, or aborted.
     * @private
     */
    private processStreamingResponse;
    /**
     * Executes a function with automatic retries and exponential backoff.
     * Respects server-specified backoff times from `nextRequestPolicy`.
     * @param fetchFn - The function to execute.
     * @param maxRetries - The maximum number of retry attempts.
     * @returns A promise that resolves to `true` on success, or `false` if all retries fail.
     * @private
     */
    private executeWithRetry;
    /**
     * Decodes a UMP part using the provided decoder.
     * @param part
     * @param decoder
     * @private
     */
    private decodePart;
    /**
     * Handles `FORMAT_INITIALIZATION_METADATA` parts.
     * Creates and stores a new `InitializedFormat` entry.
     * @private
     */
    private handleFormatInitializationMetadata;
    /**
     * Handles `NEXT_REQUEST_POLICY` parts.
     * Stores the server's policy for backoff time and playback cookies.
     * @private
     */
    private handleNextRequestPolicy;
    /**
     * Handles `SABR_ERROR` parts.
     * Throws an error to terminate the current request attempt.
     * @throws {Error} Always throws with the SABR error details.
     * @private
     */
    private handleSabrError;
    /**
     * Handles `SABR_REDIRECT` parts.
     * Updates the streaming URL to the new location provided by the server.
     * @private
     */
    private handleSabrRedirect;
    /**
     * Handles `SABR_CONTEXT_UPDATE` parts.
     * Updates the client's context state based on server instructions.
     * @private
     */
    private handleSabrContextUpdate;
    /**
     * Handles `SABR_CONTEXT_SENDING_POLICY` parts.
     * Updates which contexts should be sent in future requests.
     * @private
     */
    private handleSabrContextSendingPolicy;
    /**
     * Handles `STREAM_PROTECTION_STATUS` parts.
     * Emits updates and handles critical statuses like required attestation.
     * @throws {Error} If attestation is required (status 3).
     * @private
     */
    private handleStreamProtectionStatus;
    /**
     * Handles `RELOAD_PLAYER_RESPONSE` parts.
     * Emits an event with reload parameters and terminates the session.
     * @throws {Error} Always throws to terminate the current streaming session.
     * @private
     */
    private handleReloadPlayerResponse;
    /**
     * Handles `MEDIA_HEADER` parts.
     * Creates an entry in the `partialSegmentQueue` for the upcoming media chunks.
     * @private
     */
    private handleMediaHeader;
    /**
     * Handles `MEDIA` parts.
     * Buffers media data chunks associated with a specific header ID.
     * @private
     */
    private handleMedia;
    /**
     * Handles `MEDIA_END` parts.
     * Finalizes a segment, enqueues its data to the appropriate stream, and updates tracking.
     * @private
     */
    private handleMediaEnd;
    /**
     * Validates and corrects the stream duration based on format initialization metadata.
     * @param formatInitializationMetadata - The metadata from an initialized format.
     * @private
     */
    private validateAndCorrectDuration;
    /**
     * Validates downloaded segments for completeness and consistency after the stream finishes.
     * Checks for duration coverage, missing segments, and duplicates.
     * @private
     */
    private validateDownloadedSegments;
    /**
     * Resets the internal state of the stream.
     * Clears all maps, resets counters, and re-initializes the progress tracker.
     * @private
     */
    private resetState;
    /**
     * Handles errors during the streaming process.
     * @param error - The error that occurred.
     * @param notifyControllers - Whether to propagate the error to the stream controllers.
     * @private
     */
    private errorHandler;
}
export {};
