/**
 * Blocked Cache Service
 *
 * Maintains a materialized view of blocked elements for efficient ready-work queries.
 * The blocked_cache table provides ~25x speedup for large datasets by avoiding
 * recursive dependency checks on every query.
 *
 * Blocking Rules:
 * - `blocks` dependency: Blocked element waits for blocker to close
 * - `parent-child` dependency: Blocked element (child) inherits blocked state from blocker (parent) (transitive)
 * - `awaits` dependency: Blocked element waits until gate is satisfied (timer, approval, etc.)
 *
 * Cache Invalidation Triggers:
 * - Blocking dependency added/removed
 * - Element status changes (especially closing)
 * - Gate satisfaction changes
 * - Parent blocking state changes
 */
import type { StorageBackend } from '@stoneforge/storage';
import type { ElementId, EntityId, DependencyType, AwaitsMetadata } from '@stoneforge/core';
/**
 * Blocking information for an element
 */
export interface BlockingInfo {
    /** The element that is blocked */
    elementId: ElementId;
    /** The element causing the block */
    blockedBy: ElementId;
    /** Human-readable reason */
    reason: string;
    /** Status before becoming blocked (for restoration) */
    previousStatus?: string | null;
}
/**
 * Result of a cache rebuild operation
 */
export interface CacheRebuildResult {
    /** Number of elements checked */
    elementsChecked: number;
    /** Number of elements added to blocked cache */
    elementsBlocked: number;
    /** Time taken in milliseconds */
    durationMs: number;
}
/**
 * Options for gate checking
 */
export interface GateCheckOptions {
    /** Current time for timer gate checks (defaults to now) */
    currentTime?: Date;
}
/**
 * Callback for automatic status transitions
 */
export interface StatusTransitionCallback {
    /**
     * Called when an element should transition to blocked status
     * @param elementId - The element to block
     * @param previousStatus - The status to save for later restoration
     */
    onBlock: (elementId: ElementId, previousStatus: string) => void;
    /**
     * Called when an element should transition from blocked status
     * @param elementId - The element to unblock
     * @param statusToRestore - The status to restore to
     */
    onUnblock: (elementId: ElementId, statusToRestore: string) => void;
}
/**
 * Service for managing the blocked elements cache
 */
export declare class BlockedCacheService {
    private readonly db;
    private statusCallback?;
    constructor(db: StorageBackend);
    /**
     * Set the callback for automatic status transitions
     * This allows the service to notify when elements should be blocked/unblocked
     */
    setStatusTransitionCallback(callback: StatusTransitionCallback): void;
    /**
     * Check if an element is blocked
     *
     * @param elementId - Element to check
     * @returns Blocking info if blocked, null if not blocked
     */
    isBlocked(elementId: ElementId): BlockingInfo | null;
    /**
     * Get all blocked elements
     *
     * @returns Array of blocking info for all blocked elements
     */
    getAllBlocked(): BlockingInfo[];
    /**
     * Get all elements blocked by a specific element
     *
     * @param blockerId - The element causing blocks
     * @returns Array of element IDs blocked by this element
     */
    getBlockedBy(blockerId: ElementId): ElementId[];
    /**
     * Count blocked elements
     */
    count(): number;
    /**
     * Add a blocking entry to the cache
     *
     * @param elementId - Element being blocked
     * @param blockedBy - Element causing the block
     * @param reason - Human-readable reason
     * @param previousStatus - The element's status before becoming blocked
     */
    addBlocked(elementId: ElementId, blockedBy: ElementId, reason: string, previousStatus?: string | null): void;
    /**
     * Remove a blocking entry from the cache
     *
     * @param elementId - Element to unblock
     */
    removeBlocked(elementId: ElementId): void;
    /**
     * Clear all entries from the cache
     */
    clear(): void;
    /**
     * Check if an element is in a completed state (doesn't block others)
     *
     * @param elementId - Element to check
     * @returns true if element is completed/closed/tombstone
     */
    private isElementCompleted;
    /**
     * Check if a blocker element is in a completed state (no longer blocking)
     *
     * @param blockerId - The blocker element to check
     * @returns true if blocker is completed/closed/tombstone (no longer blocking)
     */
    isBlockerCompleted(blockerId: ElementId): boolean;
    /**
     * Get the current status of an element
     *
     * @param elementId - Element to check
     * @returns The element's status, or null if not found or no status
     */
    getElementStatus(elementId: ElementId): string | null;
    /**
     * Check if element is a task (has status field)
     */
    isTask(elementId: ElementId): boolean;
    /**
     * Check if element is a plan
     */
    isPlan(elementId: ElementId): boolean;
    /**
     * Check if an awaits gate is satisfied
     *
     * @param metadata - The awaits dependency metadata
     * @param options - Gate check options
     * @returns true if gate is satisfied (not blocking)
     */
    isGateSatisfied(metadata: AwaitsMetadata, options?: GateCheckOptions): boolean;
    /**
     * Compute the blocking state for a single element
     *
     * @param elementId - Element to check
     * @param options - Gate check options
     * @returns Blocking info if blocked, null if not blocked
     */
    computeBlockingState(elementId: ElementId, options?: GateCheckOptions): BlockingInfo | null;
    /**
     * Update blocking state for an element after a dependency change
     *
     * Handles automatic status transitions:
     * - When element becomes blocked: saves current status and triggers BLOCKED transition
     * - When element becomes unblocked: restores previous status
     *
     * @param elementId - Element whose dependencies changed
     * @param options - Gate check options
     */
    invalidateElement(elementId: ElementId, options?: GateCheckOptions): void;
    /**
     * Update blocking state for all elements that depend on a changed element
     * Called when an element's status changes (especially when completing)
     *
     * @param changedId - Element whose status changed
     * @param options - Gate check options
     */
    invalidateDependents(changedId: ElementId, options?: GateCheckOptions): void;
    /**
     * Recursively invalidate children of an element
     * Used for transitive parent-child blocking
     *
     * @param parentId - Parent element
     * @param options - Gate check options
     * @param visited - Set of already visited elements (cycle prevention)
     */
    private invalidateChildren;
    /**
     * Result of a gate satisfaction operation
     */
    /**
     * Mark an external or webhook gate as satisfied.
     * Updates the dependency metadata and recomputes blocking state.
     *
     * @param blockedId - Element that has the awaits dependency
     * @param blockerId - Blocker element ID of the awaits dependency
     * @param actor - Entity marking the gate as satisfied
     * @param options - Gate check options
     * @returns True if gate was found and satisfied, false if not found
     */
    satisfyGate(blockedId: ElementId, blockerId: ElementId, actor: EntityId, options?: GateCheckOptions): boolean;
    /**
     * Record an approval for an approval gate.
     * Updates the dependency metadata with the new approver.
     *
     * @param blockedId - Element that has the awaits dependency
     * @param blockerId - Blocker element ID of the awaits dependency
     * @param approver - Entity recording their approval
     * @param options - Gate check options
     * @returns Object indicating success and current approval count
     */
    recordApproval(blockedId: ElementId, blockerId: ElementId, approver: EntityId, options?: GateCheckOptions): {
        success: boolean;
        currentCount: number;
        requiredCount: number;
        satisfied: boolean;
    };
    /**
     * Remove an approval from an approval gate.
     *
     * @param blockedId - Element that has the awaits dependency
     * @param blockerId - Blocker element ID of the awaits dependency
     * @param approver - Entity removing their approval
     * @param options - Gate check options
     * @returns Object indicating success and current approval count
     */
    removeApproval(blockedId: ElementId, blockerId: ElementId, approver: EntityId, options?: GateCheckOptions): {
        success: boolean;
        currentCount: number;
        requiredCount: number;
        satisfied: boolean;
    };
    /**
     * Rebuild the entire blocked cache from scratch
     *
     * This is useful for:
     * - Initial population after migration
     * - Recovery from cache corruption
     * - Periodic consistency checks
     *
     * The rebuild processes elements in topological order (parents before children)
     * to ensure transitive blocking is computed correctly.
     *
     * @param options - Gate check options
     * @returns Rebuild statistics
     */
    rebuild(options?: GateCheckOptions): CacheRebuildResult;
    /**
     * Handle a blocking dependency being added
     *
     * @param blockedId - Element that is waiting/blocked
     * @param blockerId - Element doing the blocking
     * @param type - Type of dependency
     * @param metadata - Dependency metadata (for awaits)
     * @param options - Gate check options
     */
    onDependencyAdded(blockedId: ElementId, blockerId: ElementId, type: DependencyType, _metadata?: Record<string, unknown>, options?: GateCheckOptions): void;
    /**
     * Handle a blocking dependency being removed
     *
     * @param blockedId - Element that had a blocking dependency removed
     * @param blockerId - Element that was doing the blocking
     * @param type - Type of dependency that was removed
     * @param options - Gate check options
     */
    onDependencyRemoved(blockedId: ElementId, blockerId: ElementId, type: DependencyType, options?: GateCheckOptions): void;
    /**
     * Handle an element's status changing
     *
     * @param elementId - Element whose status changed
     * @param oldStatus - Previous status
     * @param newStatus - New status
     * @param options - Gate check options
     */
    onStatusChanged(elementId: ElementId, oldStatus: string | null, newStatus: string, options?: GateCheckOptions): void;
    /**
     * Handle an element being deleted
     *
     * @param elementId - Element that was deleted
     * @param options - Gate check options
     */
    onElementDeleted(elementId: ElementId, options?: GateCheckOptions): void;
}
/**
 * Create a new BlockedCacheService instance
 */
export declare function createBlockedCacheService(db: StorageBackend): BlockedCacheService;
//# sourceMappingURL=blocked-cache.d.ts.map