/**
 * Event Bus Service
 *
 * Central pub/sub service for agent lifecycle events. Agents publish events
 * (idle, busy, active, inactive) and subscribers receive notifications when
 * matching events occur. Notifications are delivered via the MessageQueueService
 * to the orchestrator terminal.
 *
 * @module services/event-bus/event-bus
 */
import { EventEmitter } from 'events';
import type { MessageQueueService } from '../messaging/message-queue.service.js';
import type { SlackThreadStoreService } from '../slack/slack-thread-store.service.js';
import type { AgentEvent, EventSubscription, CreateSubscriptionInput, EventType } from '../../types/event-bus.types.js';
/**
 * In-process event handler signature used by {@link EventBusService.onInProcess}.
 *
 * Handlers may be sync or async. Async handlers run concurrently with the
 * publisher's synchronous control flow — `publish()` does NOT await pending
 * promises, but rejected promises are caught and logged, never propagated.
 */
export type InProcessEventHandler = (event: AgentEvent) => void | Promise<void>;
/**
 * Detach function returned by {@link EventBusService.onInProcess}. Invoke to
 * unregister the handler from the bus. Idempotent — calling more than once is
 * a no-op.
 */
export type InProcessUnsubscribe = () => void;
/**
 * EventBusService manages event subscriptions and publishes agent lifecycle
 * events. When an event matches a subscription, a notification message is
 * enqueued into the MessageQueueService for delivery to the subscriber.
 *
 * @example
 * ```typescript
 * const eventBus = new EventBusService();
 * eventBus.setMessageQueueService(queueService);
 *
 * eventBus.subscribe({
 *   eventType: 'agent:idle',
 *   filter: { sessionName: 'agent-joe' },
 *   subscriberSession: 'crewly-orc',
 *   oneShot: true,
 * });
 *
 * eventBus.publish(agentIdleEvent);
 * ```
 */
export declare class EventBusService extends EventEmitter {
    private logger;
    private subscriptions;
    private messageQueueService;
    private slackThreadStore;
    private cleanupInterval;
    private deliveryCount;
    /**
     * Buffered notifications pending delivery after debounce window.
     * Key: `${subscriberSession}:${event.sessionName}` for per-agent dedup.
     * When the same agent fires multiple events within the debounce window,
     * only the latest event is kept (deduplication by overwrite).
     */
    private pendingNotifications;
    /** Debounce timer for batching event notifications */
    private batchTimer;
    /** Hard-deadline timer that forces a flush even if debounce keeps resetting */
    private maxWaitTimer;
    /**
     * Dedup guard for publish(): ignores duplicate events for the same
     * (type, sessionName) within EVENT_DEBOUNCE_WINDOW_MS (5s).
     * Key: `${eventType}:${sessionName}`, value: timestamp (ms).
     */
    private recentPublishMap;
    /**
     * In-process subscribers keyed by event type. Used by internal services
     * (EventToWorkItemBridge, LEARN-1's auto-record-learning subscriber) that
     * need to react to events synchronously without going through the
     * agent-session subscription queue.
     *
     * The agent-session subscriptions ({@link subscriptions}) and these
     * in-process handlers are intentionally separate — the former routes
     * through MessageQueueService and is rate-limited / debounced, the
     * latter fires immediately and is meant for trusted internal callers.
     */
    private inProcessHandlers;
    constructor();
    /**
     * Set the MessageQueueService instance for delivering notifications.
     *
     * @param service - The MessageQueueService instance
     */
    setMessageQueueService(service: MessageQueueService): void;
    /**
     * Set the SlackThreadStoreService for enriching notifications with thread paths.
     *
     * @param store - The SlackThreadStoreService instance
     */
    setSlackThreadStore(store: SlackThreadStoreService): void;
    /**
     * Create a new event subscription.
     *
     * @param input - Subscription configuration
     * @returns The created EventSubscription
     * @throws Error if input is invalid or limits are exceeded
     */
    subscribe(input: CreateSubscriptionInput): EventSubscription;
    /**
     * Remove a subscription by ID.
     *
     * @param subscriptionId - ID of the subscription to remove
     * @returns True if the subscription was found and removed
     */
    unsubscribe(subscriptionId: string): boolean;
    /**
     * Publish an event to all matching subscriptions.
     * For each match, formats a notification message and enqueues it
     * into the MessageQueueService for delivery to the subscriber.
     *
     * @param event - The agent lifecycle event to publish
     */
    publish(event: AgentEvent): void;
    /**
     * Register an in-process handler for one or more event types.
     *
     * Used by trusted internal services (EventToWorkItemBridge, LEARN-1's
     * auto-record-learning subscriber) that need synchronous reactivity to
     * the event stream without going through the agent-session subscription
     * queue. These handlers fire from `publish()` immediately after the
     * `event_published` EventEmitter signal, before the debounced
     * notification flush, so callers can rely on the same publish ordering
     * semantics as `EventEmitter.on('event_published', …)` listeners.
     *
     * Handler errors are isolated:
     *   - synchronous throws are caught and logged
     *   - rejected promises returned by async handlers are caught and logged
     *   - neither propagates to other in-process handlers nor to the
     *     publisher's `publish()` call site
     *
     * Returned `unsubscribe` is idempotent.
     *
     * @param eventTypes - One event type or an array of event types to listen for
     * @param handler - Sync or async handler invoked once per matching event
     * @returns A function that detaches the handler when called
     *
     * @example
     * ```typescript
     * const unsubscribe = eventBus.onInProcess(
     *   ['task:done_by_worker', 'task:rejected'],
     *   async (event) => {
     *     await bridge.handleTaskEvent(event);
     *   },
     * );
     * // Later: unsubscribe();
     * ```
     */
    onInProcess(eventTypes: EventType | EventType[], handler: InProcessEventHandler): InProcessUnsubscribe;
    /**
     * Invoke every in-process handler registered for an event's type.
     * Sync throws and async rejections are caught + logged; never propagated.
     *
     * @param event - The event being published
     */
    private dispatchInProcess;
    /**
     * List subscriptions, optionally filtered by subscriber session.
     *
     * @param subscriberSession - Optional session name to filter by
     * @returns Array of matching subscriptions
     */
    listSubscriptions(subscriberSession?: string): EventSubscription[];
    /**
     * Get a specific subscription by ID.
     *
     * @param subscriptionId - ID of the subscription
     * @returns The subscription or undefined
     */
    getSubscription(subscriptionId: string): EventSubscription | undefined;
    /**
     * Get event bus statistics.
     *
     * @returns Stats object with subscription and delivery counts
     */
    getStats(): {
        subscriptionCount: number;
        deliveryCount: number;
    };
    /**
     * Stop the cleanup timer and clear all subscriptions.
     */
    cleanup(): void;
    /**
     * Buffer a notification for debounced delivery with per-agent deduplication.
     * Critical events (task:completed, task:failed, agent:inactive, etc.) bypass
     * the debounce buffer and are delivered immediately to avoid notification delay.
     *
     * @param sub - The subscription whose subscriber should receive the message
     * @param message - The formatted notification message
     * @param event - The original agent event
     */
    private bufferNotification;
    /**
     * Deliver a notification immediately without debouncing.
     * Used for critical events that must reach the subscriber ASAP.
     *
     * @param subscriberSession - The session to deliver to
     * @param message - The formatted notification message
     */
    private deliverImmediately;
    /**
     * Flush all buffered notifications as a single combined message.
     * Groups by subscriber session and delivers one enqueue per subscriber.
     */
    private flushNotifications;
    /**
     * Check if an event matches a subscription's type and filter criteria.
     *
     * @param event - The event to check
     * @param sub - The subscription to match against
     * @returns True if the event matches the subscription
     */
    private matchesSubscription;
    /**
     * Format a notification message for an event and subscription.
     *
     * @param event - The event that triggered the notification
     * @param sub - The subscription that matched
     * @returns Formatted notification message string
     */
    private formatNotification;
    /**
     * Get the number of subscriptions for a given subscriber session.
     *
     * @param subscriberSession - Session name to count
     * @returns Number of subscriptions
     */
    private getSubscriptionCountForSession;
    /**
     * Start the periodic cleanup timer to remove expired subscriptions.
     */
    private startCleanup;
    /**
     * Remove all expired subscriptions.
     */
    private cleanupExpired;
}
//# sourceMappingURL=event-bus.service.d.ts.map