import { GoodVibesSdkError } from '@pellux/goodvibes-errors';
import type { FeatureFlagManager } from '../runtime/feature-flags/index.js';
/**
 * The three possible outcomes for a single integration delivery attempt.
 *
 * - `delivered`   — message reached the destination successfully
 * - `retrying`    — delivery failed with a retryable error; queued for retry
 * - `dead_letter` — all retry attempts exhausted or terminal failure; moved to DLQ
 */
export type DeliveryOutcome = 'delivered' | 'retrying' | 'dead_letter';
/**
 * Classification of a delivery failure.
 *
 * - `retryable` — transient error; should be retried with backoff
 *   (network timeout, HTTP 429, HTTP 5xx)
 * - `terminal`  — permanent error; should not be retried
 *   (HTTP 400/401/403/404, invalid URL, message too large)
 */
export type DeliveryFailureClass = 'retryable' | 'terminal';
/**
 * Classify a delivery error as retryable or terminal.
 *
 * Rules (in order):
 * 1. Network errors with no HTTP status → retryable (timeout, ECONNREFUSED, etc.)
 * 2. HTTP 4xx (except 408/429) → terminal (auth failure, bad request, not found)
 * 3. HTTP 429 / 5xx → retryable
 * 4. Unknown → retryable (prefer retry over silent drop)
 */
export declare function classifyDeliveryError(error: unknown): DeliveryFailureClass;
/** Typed delivery error that carries an explicit failure classification. */
export declare class DeliveryError extends GoodVibesSdkError {
    readonly failureClass: DeliveryFailureClass;
    readonly statusCode?: number | undefined;
    readonly code: 'DELIVERY_ERROR';
    constructor(message: string, failureClass: DeliveryFailureClass, statusCode?: number | undefined);
}
/**
 * A single entry in the dead-letter queue.
 * Immutable snapshot of a delivery that exhausted all retry attempts.
 */
export interface DeadLetterEntry {
    /** Unique entry identifier. */
    readonly id: string;
    /** Integration channel (e.g. "slack", "discord", "webhook"). */
    readonly channel: string;
    /** Event name that triggered the delivery. */
    readonly event: string;
    /** Message payload that failed to deliver. */
    readonly payload: string;
    /** Epoch ms when the entry was created (first attempt). */
    readonly createdAt: number;
    /** Epoch ms when the entry moved to the DLQ. */
    readonly deadAt: number;
    /** Number of delivery attempts made. */
    readonly attempts: number;
    /** Final error message. */
    readonly finalError: string;
    /** Failure class of the final error. */
    readonly failureClass: DeliveryFailureClass;
}
/** Counters for delivery SLO tracking. */
export interface DeliveryMetrics {
    /** Total delivery attempts (all channels combined). */
    readonly totalAttempts: number;
    /** Successfully delivered messages. */
    readonly delivered: number;
    /** Messages currently queued for retry. */
    readonly retrying: number;
    /** Messages moved to the dead-letter queue. */
    readonly deadLettered: number;
    /** Total entries in the DLQ (including previously replayed). */
    readonly dlqSize: number;
}
/** Configuration for the DeliveryQueue. */
export interface DeliveryQueueConfig {
    /**
     * Maximum retry attempts after the initial delivery attempt.
     * E.g., maxRetries: 3 means 4 total attempts (1 initial + 3 retries).
     */
    maxRetries: number;
    /** Initial backoff delay in ms (default: 1000). */
    initialDelayMs: number;
    /** Maximum backoff delay in ms (default: 30_000). */
    maxDelayMs: number;
    /** Maximum dead-letter queue size; oldest entries evicted when exceeded (default: 500). */
    maxDlqSize: number;
    /**
     * When true, SLO enforcement is active: dead-letter events are logged at
     * error level and metrics are updated. When false, failures are logged at
     * warn level only.
     *
     * Controlled by the `integration-delivery-slo` feature flag.
     */
    sloEnforced: boolean;
}
export interface DeliveryQueueOptions extends Partial<DeliveryQueueConfig> {
    readonly featureFlags?: Pick<FeatureFlagManager, 'isEnabled'> | null | undefined;
}
/**
 * Delivery queue with retry/backoff and dead-letter storage.
 *
 * Wrap any integration send operation with `enqueue()`. The queue:
 *  1. Attempts delivery immediately.
 *  2. On retryable failure: schedules retry with exponential backoff + jitter.
 *  3. On terminal failure or exhausted retries: moves entry to DLQ.
 *  4. Emits `delivery:dead_letter` events to registered listeners.
 *
 * Dead-letter entries can be replayed via `replay()` or cleared with `clearDlq()`.
 *
 * Enable SLO enforcement via the `integration-delivery-slo` feature flag to
 * surface dead-letter failures as error-level log entries and expose them in
 * integration diagnostics.
 */
export declare class DeliveryQueue {
    private readonly _config;
    private readonly _dlq;
    private readonly _pending;
    private readonly _timers;
    private readonly _listeners;
    private _totalAttempts;
    private _delivered;
    private _retrying;
    private _deadLettered;
    constructor(config?: DeliveryQueueOptions);
    /**
     * Enqueue a delivery attempt.
     *
     * @param channel - Integration channel identifier (e.g. "slack").
     * @param event   - Event name for tracing.
     * @param payload - Message text to deliver.
     * @param deliver - Async function that performs the actual delivery.
     * @returns The delivery outcome for the immediate attempt.
     */
    enqueue(channel: string, event: string, payload: string, deliver: () => Promise<void>): Promise<DeliveryOutcome>;
    /**
     * Replay all dead-letter entries.
     *
     * Each entry is re-enqueued with a fresh retry budget. The DLQ is cleared
     * on a per-entry basis as each replayed entry resolves.
     *
     * @param deliver - Optional delivery function override. When omitted,
     *   the original delivery function is not available (DLQ is persistent
     *   storage), so a no-op is used and the caller must provide one.
     *
     * @returns Array of per-entry replay results.
     */
    replay(deliver: (entry: DeadLetterEntry) => Promise<void>): Promise<Array<{
        id: string;
        outcome: DeliveryOutcome;
    }>>;
    /**
     * Register a listener invoked whenever an entry moves to the DLQ.
     * Returns an unsubscribe function.
     */
    onDeadLetter(listener: (entry: DeadLetterEntry) => void): () => void;
    /** Get current dead-letter queue contents (snapshot). */
    getDlq(): readonly DeadLetterEntry[];
    /** Clear all dead-letter entries. */
    clearDlq(): number;
    /** Whether SLO enforcement is active for this queue. */
    get sloEnforced(): boolean;
    /** Current delivery metrics snapshot. */
    getMetrics(): DeliveryMetrics;
    /**
     * Cancel all pending retry timers and clear internal state.
     * Call on shutdown to prevent timer leaks.
     */
    dispose(): void;
    private _attempt;
    private _moveToDlq;
    private _computeDelay;
}
/**
 * Snapshot of a DeliveryQueue for display in integration diagnostics.
 */
export interface IntegrationQueueStatus {
    /** Integration channel identifier. */
    readonly channel: string;
    /** Current delivery metrics. */
    readonly metrics: DeliveryMetrics;
    /** Dead-letter entries (most recent first, capped at 50 for display). */
    readonly dlqEntries: readonly DeadLetterEntry[];
    /** Whether SLO enforcement is active. */
    readonly sloEnforced: boolean;
    /** Epoch ms of this snapshot. */
    readonly capturedAt: number;
}
/**
 * Produce a diagnostics snapshot for a channel's DeliveryQueue.
 */
export declare function snapshotQueueStatus(channel: string, queue: DeliveryQueue, sloEnforced: boolean): IntegrationQueueStatus;
//# sourceMappingURL=delivery.d.ts.map