/**
 * Incremental Scanner Cache
 *
 * Caches scanner results to enable incremental scanning. Only changed files
 * are re-scanned, dramatically improving performance on subsequent runs.
 *
 * Cache structure:
 * ```
 * .vaspera/cache/scanners/{scanner}/{hash}.json
 * ```
 *
 * Cache key: sha256(filePath + fileHash + scannerVersion + ruleHash)
 *
 * @module scanners/cache
 */
import type { ScannerType, DeterministicFinding, ScannerResult } from "./types.js";
/**
 * Cache entry for a single file's scanner results
 */
export interface ScannerCacheEntry {
    /** Cache format version */
    version: 1;
    /** Scanner type */
    scanner: ScannerType;
    /** Scanner version that produced this result */
    scannerVersion: string;
    /** Hash of the rules/config used */
    ruleHash: string;
    /** Relative file path */
    filePath: string;
    /** Hash of file contents when scanned */
    fileHash: string;
    /** Findings from the scan */
    findings: DeterministicFinding[];
    /** Timestamp when cached */
    cachedAt: string;
    /** Scan duration in ms (for metrics) */
    scanDuration: number;
}
/**
 * Cache statistics
 */
export interface CacheStats {
    /** Total entries in cache */
    totalEntries: number;
    /** Total size in bytes */
    totalSizeBytes: number;
    /** Entries by scanner */
    byScanner: Record<ScannerType, number>;
    /** Oldest entry timestamp */
    oldestEntry?: string;
    /** Newest entry timestamp */
    newestEntry?: string;
}
/**
 * Cache lookup result
 */
export interface CacheLookupResult {
    /** Whether a valid cache entry was found */
    hit: boolean;
    /** The cached entry if found */
    entry?: ScannerCacheEntry;
    /** Reason for cache miss */
    missReason?: "not_found" | "version_mismatch" | "rule_mismatch" | "file_changed" | "expired";
}
/**
 * Options for the scanner cache
 */
export interface ScannerCacheOptions {
    /** Maximum number of entries per scanner (default: 10000) */
    maxEntriesPerScanner?: number;
    /** Maximum age of cache entries in ms (default: 7 days) */
    maxAgeMs?: number;
    /** Cache directory path (default: .vaspera/cache/scanners) */
    cacheDir?: string;
}
/**
 * Scanner cache manager
 *
 * Provides LRU cache with configurable limits per scanner type.
 */
export declare class ScannerCache {
    private readonly cacheDir;
    private readonly maxEntriesPerScanner;
    private readonly maxAgeMs;
    private readonly projectPath;
    constructor(projectPath: string, options?: ScannerCacheOptions);
    /**
     * Generate a cache key for a file + scanner + version + rules combination
     */
    generateCacheKey(filePath: string, fileHash: string, scanner: ScannerType, scannerVersion: string, ruleHash: string): string;
    /**
     * Get the cache file path for a given key
     */
    private getCachePath;
    /**
     * Ensure cache directory exists
     */
    private ensureCacheDir;
    /**
     * Look up cached results for a file
     */
    lookup(filePath: string, fileHash: string, scanner: ScannerType, scannerVersion: string, ruleHash: string): Promise<CacheLookupResult>;
    /**
     * Store scanner results in cache
     */
    store(filePath: string, fileHash: string, scanner: ScannerType, scannerVersion: string, ruleHash: string, findings: DeterministicFinding[], scanDuration: number): Promise<void>;
    /**
     * Invalidate cache for a specific file
     */
    invalidate(filePath: string, scanner?: ScannerType): Promise<number>;
    /**
     * Run LRU eviction to stay within limits
     */
    evict(): Promise<number>;
    /**
     * Get cache statistics
     */
    getStats(): Promise<CacheStats>;
    /**
     * Clear all cache entries
     */
    clear(): Promise<number>;
}
/**
 * Compute hash of file contents
 */
export declare function hashFileContents(filePath: string): Promise<string>;
/**
 * Compute hash of scanner rules/config
 *
 * This is used to invalidate cache when rules change.
 */
export declare function hashRules(rules: string[] | undefined, configFile?: string): string;
/**
 * Run scanner with caching
 *
 * Wraps a scanner function to use the cache. Only scans files that:
 * 1. Are not in cache
 * 2. Have changed since last scan
 * 3. Were scanned with different scanner version or rules
 */
export declare function runScannerWithCache<T extends ScannerResult>(cache: ScannerCache, scanner: ScannerType, scannerVersion: string, ruleHash: string, files: Array<{
    path: string;
    hash: string;
}>, scanFn: (filePaths: string[]) => Promise<T>): Promise<{
    result: T;
    cacheHits: number;
    cacheMisses: number;
    savedTimeMs: number;
}>;
/**
 * Create a default scanner cache instance
 */
export declare function createScannerCache(projectPath: string, options?: ScannerCacheOptions): ScannerCache;
//# sourceMappingURL=cache.d.ts.map