/**
 * Scheduler Service
 *
 * Enhanced scheduler service with PTY compatibility, continuation-aware scheduling,
 * and adaptive scheduling based on agent activity.
 *
 * @module services/workflow/scheduler.service
 */
import { EventEmitter } from 'events';
import { ScheduledCheck } from '../../types/index.js';
import { StorageService } from '../core/storage.service.js';
import { AgentRegistrationService } from '../agent/agent-registration.service.js';
import { type MessageSource } from '../../constants.js';
import { ScheduledMessageType, EnhancedScheduledMessage, AdaptiveScheduleConfig, ScheduleContinuationParams, SchedulerStats } from '../../types/scheduler.types.js';
/**
 * Interface for ContinuationService integration
 */
interface IContinuationServiceLike {
    handleEvent(event: {
        trigger: string;
        sessionName: string;
        agentId: string;
        projectPath: string;
        timestamp: string;
        metadata: Record<string, unknown>;
    }): Promise<unknown>;
}
/**
 * Interface for ActivityMonitor integration
 */
interface IActivityMonitorLike {
    getWorkingStatusForSession(sessionName: string): Promise<'idle' | 'in_progress' | null>;
}
/**
 * Interface for TaskTrackingService integration.
 * Used to check whether a scheduled check's linked task is still active.
 */
interface ITaskTrackingServiceLike {
    getAllInProgressTasks(): Promise<{
        id: string;
        status: string;
        scheduleIds?: string[];
    }[]>;
}
/** Minimal interface for MessageQueueService to avoid circular imports. */
interface IMessageQueueServiceLike {
    enqueue(input: {
        content: string;
        conversationId: string;
        source: MessageSource;
        sourceMetadata?: Record<string, string>;
    }): unknown;
    isProcessing(): boolean;
}
/**
 * Enhanced SchedulerService with PTY compatibility
 *
 * Features:
 * - Uses PTY session backend instead of tmux
 * - Continuation-aware scheduling
 * - Adaptive scheduling based on activity
 * - Recurring check persistence to disk (survives restarts via StorageService)
 * - Backward compatible API
 *
 * ## Migration Note: SchedulerService vs MessageSchedulerService
 *
 * Both services schedule recurring messages to agent sessions, but they serve
 * different purposes and should remain separate:
 *
 * **MessageSchedulerService** — User-configured scheduled messages.
 * - Messages are persisted as `ScheduledMessage` objects with full CRUD via
 *   the frontend settings UI.
 * - Supports `delayUnit` (seconds/minutes/hours), `targetProject`, and
 *   `isActive` toggles.
 * - Uses a sequential message queue (`executeMessageSequentially`) to
 *   prevent race conditions when multiple user-configured messages fire at
 *   the same time.
 * - Loads state on startup via `loadAndScheduleAllMessages()`.
 *
 * **SchedulerService** (this class) — Programmatic/orchestrator-driven checks.
 * - Checks are created dynamically by the orchestrator via the
 *   `schedule-check` skill or internally by `scheduleDefaultCheckins`.
 * - Supports continuation-aware checks, adaptive scheduling based on
 *   agent activity, and max occurrence limits.
 * - Uses `ScheduledCheck` type with `intervalMinutes` (minutes only).
 * - Persists recurring checks to `~/.crewly/recurring-checks.json` and
 *   restores them via `restoreRecurringChecks()`.
 *
 * **Recommendation:** Keep both services. They share the same delivery
 * path (`AgentRegistrationService.sendMessageToAgent`), but unifying them
 * would require merging two different persistence models, two different
 * scheduling APIs, and two different use-case flows (UI-driven vs
 * orchestrator-driven). The sequential queue pattern from
 * MessageSchedulerService could be adopted here if concurrent recurring
 * check delivery becomes a problem in practice.
 *
 * @example
 * ```typescript
 * const scheduler = new SchedulerService(storageService);
 *
 * // Schedule default check-ins
 * const checkIds = scheduler.scheduleDefaultCheckins('agent-session');
 *
 * // Schedule a continuation check
 * const contId = scheduler.scheduleContinuationCheck({
 *   sessionName: 'agent-session',
 *   delayMinutes: 5,
 *   agentId: 'agent-1',
 *   projectPath: '/path/to/project',
 * });
 *
 * // Schedule adaptive check-in
 * await scheduler.scheduleAdaptiveCheckin('agent-session');
 * ```
 */
export declare class SchedulerService extends EventEmitter {
    private scheduledChecks;
    private oneTimeChecksData;
    private recurringChecks;
    private recurringTimeouts;
    private continuationChecks;
    private adaptiveChecks;
    private enhancedMessages;
    private _sessionBackend;
    private storageService;
    private logger;
    private continuationService;
    private activityMonitor;
    private agentRegistrationService;
    private messageQueueService;
    private deliveryInProgress;
    /** #167: Dead-letter queue — messages for offline agents, delivered when they come online. */
    private deadLetterQueue;
    /** #167: Active cron tasks keyed by check ID. */
    private cronTasks;
    /** Consecutive idle hits per recurring check ID for auto-cancel policy. */
    private recurringIdleStreak;
    /** Auto-cancel recurring checks after this many consecutive idle observations. */
    private static readonly RECURRING_IDLE_AUTO_CANCEL_THRESHOLD;
    /** #211: Consecutive delivery failures per target session for ghost session auto-cancel. */
    private consecutiveFailures;
    /** #211: Auto-cancel recurring checks after this many consecutive delivery failures (ghost sessions). */
    private static readonly GHOST_SESSION_AUTO_CANCEL_THRESHOLD;
    /** #217: Write counter for periodic temp file cleanup. */
    private writeCounter;
    /** #217: Clean up stale temp files every N writes. */
    private static readonly TEMP_CLEANUP_INTERVAL;
    /**
     * Per-agent manual check timestamps. Updated when orchestrator calls
     * get_agent_status or get_agent_logs via tool registry. Recurring checks
     * whose message mentions a recently-checked session are suppressed.
     */
    private lastManualCheck;
    /** Unique session ID generated on construction — tags all new checks so stale checks from previous sessions can be purged on restart (#169). */
    private readonly sessionId;
    /**
     * Creates a new SchedulerService
     *
     * @param storageService - Storage service for delivery logs
     */
    constructor(storageService: StorageService);
    /**
     * Get the current session ID for this SchedulerService instance.
     *
     * @returns The unique session ID
     */
    getSessionId(): string;
    /**
     * Record that the orchestrator manually checked an agent's status or logs.
     * Recurring checks whose message mentions this session will be suppressed
     * if they fire within the agent's recurring interval.
     *
     * @param agentSession - The agent session name that was checked
     */
    recordManualCheck(agentSession: string): void;
    /**
     * Check whether a recurring check should be suppressed because the
     * orchestrator recently checked the same agent manually.
     *
     * @param message - The check message content
     * @param intervalMinutes - The recurring interval in minutes
     * @returns true if a manual check happened within the interval
     */
    private wasRecentlyManuallyChecked;
    /**
     * Get the session backend, lazily initializing if needed
     *
     * @returns Promise resolving to the session backend
     */
    private getBackend;
    /**
     * Get the session backend synchronously (may return null if not initialized)
     *
     * @returns Session backend or null
     */
    private get sessionBackend();
    /**
     * Set the continuation service for integration
     *
     * @param service - Continuation service instance
     */
    setContinuationService(service: IContinuationServiceLike): void;
    /**
     * Set the activity monitor for adaptive scheduling
     *
     * @param monitor - Activity monitor instance
     */
    setActivityMonitor(monitor: IActivityMonitorLike): void;
    /**
     * Set the AgentRegistrationService for reliable message delivery.
     * Called after both services are constructed to avoid circular dependencies.
     *
     * @param service - The AgentRegistrationService instance
     */
    setAgentRegistrationService(service: AgentRegistrationService): void;
    /**
     * Legacy — setTaskTrackingService is a no-op. Task-aware cleanup now uses TaskPool.
     * @param _service - Ignored
     */
    setTaskTrackingService(_service: ITaskTrackingServiceLike): void;
    /**
     * Set the MessageQueueService for serialized orchestrator delivery.
     * When set, scheduled checks targeting the orchestrator are routed through
     * the queue instead of direct PTY delivery, preventing interruption of
     * in-flight chat messages.
     *
     * @param service - MessageQueueService instance (must have enqueue method)
     */
    setMessageQueueService(service: IMessageQueueServiceLike): void;
    /**
     * Resolve the runtime type for a target session by looking up the team member.
     * Falls back to claude-code if the member is not found.
     *
     * @param sessionName - The session name to look up
     * @returns The runtime type for the session
     */
    private resolveRuntimeType;
    /**
     * Check if a task has been completed by querying the TaskPool.
     *
     * @param taskId - The task/work-item ID to check
     * @returns true if task is done/missing, false if still active
     */
    private isTaskCompleted;
    /**
     * Schedule a one-time check-in for an agent
     *
     * @param targetSession - Target session name
     * @param minutes - Delay in minutes
     * @param message - Message to send
     * @param type - Type of scheduled message
     * @returns Check ID
     */
    scheduleCheck(targetSession: string, minutes: number, message: string, type?: ScheduledMessageType, options?: {
        label?: string;
        persistent?: boolean;
        timezone?: string;
        recurrenceType?: 'interval' | 'daily' | 'weekdays' | 'weekly';
        timeOfDay?: string;
        dayOfWeek?: number;
    }): string;
    /**
     * Schedule recurring check-ins for an agent
     *
     * @param targetSession - Target session name
     * @param intervalMinutes - Interval in minutes
     * @param message - Message to send
     * @param type - Type of scheduled message
     * @param maxOccurrences - Maximum number of times the check fires (undefined = unlimited)
     * @returns Check ID
     */
    scheduleRecurringCheck(targetSession: string, intervalMinutes: number, message: string, type?: ScheduledMessageType, maxOccurrences?: number, options?: {
        label?: string;
        persistent?: boolean;
        timezone?: string;
        recurrenceType?: 'interval' | 'daily' | 'weekdays' | 'weekly';
        timeOfDay?: string;
        dayOfWeek?: number;
        taskId?: string;
    }): string;
    /**
     * #167: Schedule a recurring check using a cron expression.
     * Supports standard 5-field cron syntax (minute hour day-of-month month day-of-week).
     * Falls back to intervalMinutes-based scheduling if cron expression is invalid.
     *
     * @param targetSession - Target session name
     * @param cronExpression - Cron expression (e.g., '0 9 * * *' for daily at 9am)
     * @param message - Message to send
     * @param type - Type of scheduled message
     * @param maxOccurrences - Maximum number of times the check fires
     * @param options - Additional scheduling options
     * @returns Check ID
     */
    scheduleCronCheck(targetSession: string, cronExpression: string, message: string, type?: ScheduledMessageType, maxOccurrences?: number, options?: {
        label?: string;
        taskId?: string;
    }): string;
    /**
     * Schedule default check-ins for a new agent
     *
     * @param sessionName - Session name
     * @returns Array of check IDs
     */
    scheduleDefaultCheckins(sessionName: string): string[];
    /**
     * Schedule a continuation check
     *
     * Continuation checks trigger the ContinuationService instead of
     * sending a regular message.
     *
     * @param params - Continuation parameters
     * @returns Check ID
     */
    scheduleContinuationCheck(params: ScheduleContinuationParams): string;
    /**
     * Schedule an adaptive check-in based on agent activity
     *
     * Adjusts the check interval based on whether the agent is active or idle.
     *
     * @param sessionName - Session name
     * @param config - Adaptive configuration (uses defaults if not provided)
     * @returns Check ID
     */
    scheduleAdaptiveCheckin(sessionName: string, config?: AdaptiveScheduleConfig): Promise<string>;
    /**
     * Get activity info for a session
     *
     * @param sessionName - Session name
     * @returns Activity information
     */
    private getActivityInfo;
    /**
     * Cancel a scheduled check-in.
     *
     * When a check is found in memory, it is cleared from both the in-memory
     * maps and the persisted JSON file. When NOT found in memory (e.g. after a
     * server restart), the method still attempts to remove the entry from the
     * persisted file as a fallback (#290).
     *
     * @param checkId - Check ID to cancel
     * @returns true if the check was found and cancelled (in-memory or on disk)
     */
    cancelCheck(checkId: string): boolean;
    /**
     * Cancel all checks for a specific session
     *
     * @param sessionName - Session name
     */
    cancelAllChecksForSession(sessionName: string): void;
    /**
     * Cancel all scheduled checks, optionally filtered by session or minimum age.
     *
     * @param filter - Optional filter criteria
     * @param filter.session - Only cancel checks targeting this session
     * @param filter.olderThanMinutes - Only cancel checks created more than N minutes ago
     * @returns Number of checks cancelled
     */
    cancelAllChecks(filter?: {
        session?: string;
        olderThanMinutes?: number;
    }): number;
    /**
     * List all scheduled check-ins
     *
     * @returns Array of scheduled checks
     */
    listScheduledChecks(): ScheduledCheck[];
    /**
     * Get checks for a specific session
     *
     * @param sessionName - Session name
     * @returns Array of scheduled checks
     */
    getChecksForSession(sessionName: string): ScheduledCheck[];
    /**
     * Get enhanced message information for a check
     *
     * @param checkId - Check ID
     * @returns Enhanced message or undefined
     */
    getEnhancedMessage(checkId: string): EnhancedScheduledMessage | undefined;
    /**
     * Execute a check-in using reliable delivery via AgentRegistrationService.
     * Falls back to direct PTY write if AgentRegistrationService is not available.
     *
     * The reliable delivery path provides: prompt detection before sending,
     * two-step write (text then Enter separately), progressive delivery verification,
     * background stuck-message scanning, and retry logic.
     *
     * @param targetSession - Target session name
     * @param message - Message to send
     */
    private executeCheck;
    /**
     * Execute a continuation check
     *
     * @param sessionName - Session name
     * @param agentId - Agent ID
     * @param projectPath - Project path
     */
    private executeContinuationCheck;
    /**
     * Set up recurring execution
     *
     * @param checkId - Check ID
     * @param intervalMinutes - Interval in minutes
     * @param targetSession - Target session
     * @param message - Message to send
     */
    private scheduleRecurringExecution;
    /**
     * Enrich a recurring check message with freshness instructions.
     * Tells the agent to query current task status rather than relying on
     * potentially stale task descriptions embedded in the original message.
     *
     * @param originalMessage - The original scheduled check message
     * @returns Enriched message with freshness instructions
     */
    private addFreshnessInstructions;
    /**
     * #167: Drain the dead-letter queue for a session that has come online.
     * Delivers all queued messages and clears the queue for that session.
     *
     * @param sessionName - The session that came online
     * @returns Number of messages delivered
     */
    drainDeadLetterQueue(sessionName: string): Promise<number>;
    /**
     * Get dead-letter queue stats.
     *
     * @returns Map of session name to queued message count
     */
    getDeadLetterQueueStats(): Record<string, number>;
    /**
     * #217: Clean up orphaned .tmp files left by atomicWriteFile crashes.
     *
     * @returns Number of temp files cleaned up
     */
    cleanupStaleTempFiles(): Promise<number>;
    /**
     * #217: Increment the write counter and trigger periodic temp file cleanup.
     */
    private triggerPeriodicTempCleanup;
    /**
     * Clean up all scheduled checks
     */
    cleanup(): void;
    /**
     * Restore recurring checks from disk after a restart.
     *
     * Reads persisted recurring check state and re-schedules each one.
     * The first execution fires after one interval from now (not from the
     * original creation time) to avoid a burst of catch-up deliveries.
     *
     * @returns Number of checks restored
     */
    restoreRecurringChecks(): Promise<number>;
    /**
     * Restore one-time checks from disk after a restart.
     *
     * Reads persisted one-time check state and re-schedules each one using the
     * remaining time until the original scheduledFor. Checks whose scheduledFor
     * time has already passed are discarded as stale.
     *
     * @returns Number of checks restored
     */
    restoreOneTimeChecks(): Promise<number>;
    /**
     * Get scheduler statistics
     *
     * @returns Statistics object
     */
    getStats(): SchedulerStats;
}
export {};
//# sourceMappingURL=scheduler.service.d.ts.map