/**
 * Distributed Policy Cache
 *
 * Redis-backed distributed cache for policy data with:
 * - Cache versioning for stale read detection
 * - Write-through caching with Redis transactions
 * - 2-phase invalidation (mark stale -> update -> confirm)
 * - Distributed locking for policy updates
 *
 * Fixes MEDIUM vulnerability: Policy evaluation cache invalidation race condition
 *
 * @packageDocumentation
 */
import { Counter, Histogram, Gauge } from 'prom-client';
import type { Policy } from './types.js';
/**
 * Policy cache hit/miss counter
 */
export declare const policyDistributedCacheOperations: Counter<"result" | "operation" | "tenant_id">;
/**
 * Policy lock contention counter
 */
export declare const policyLockContentionTotal: Counter<"result" | "operation" | "tenant_id">;
/**
 * Policy lock wait time histogram
 */
export declare const policyLockWaitSeconds: Histogram<"tenant_id">;
/**
 * Stale cache reads detected
 */
export declare const policyStaleCacheReadsTotal: Counter<"tenant_id">;
/**
 * Active policy locks gauge
 */
export declare const activePolicyLocksGauge: Gauge<string>;
/**
 * Cached policy entry with version metadata
 */
export interface CachedPolicyEntry {
    policy: Policy;
    cacheVersion: number;
    cachedAt: number;
    expiresAt: number;
}
/**
 * Policy version info stored in Redis
 */
export interface PolicyVersionInfo {
    version: number;
    checksum: string;
    updatedAt: number;
    cacheVersion: number;
    stale: boolean;
}
/**
 * Lock result
 */
export interface PolicyLockResult {
    acquired: boolean;
    lockId?: string;
    error?: string;
}
/**
 * Options for policy lock acquisition
 */
export interface PolicyLockOptions {
    /** Lock timeout in milliseconds (how long the lock is held) */
    lockTimeoutMs?: number;
    /** Maximum time to wait for acquiring the lock */
    acquireTimeoutMs?: number;
    /** Initial retry delay in milliseconds */
    retryDelayMs?: number;
}
/**
 * Distributed Policy Cache Service
 *
 * Provides distributed caching with:
 * - Cache versioning for stale read detection
 * - Write-through caching with atomic Redis transactions
 * - 2-phase invalidation to prevent race conditions
 * - Distributed locking for policy mutations
 */
export declare class DistributedPolicyCache {
    private redis;
    private activeLocks;
    private getCacheKey;
    private getVersionKey;
    private getLockKey;
    private getStaleKey;
    /**
     * Acquire a distributed lock for a policy
     *
     * @param policyId - Policy ID to lock
     * @param tenantId - Tenant ID
     * @param options - Lock options
     * @returns Lock result with lockId if acquired
     */
    acquireLock(policyId: string, tenantId: string, options?: PolicyLockOptions): Promise<PolicyLockResult>;
    /**
     * Release a distributed lock for a policy
     *
     * @param policyId - Policy ID
     * @param tenantId - Tenant ID
     * @param lockId - Lock ID from acquire
     * @returns true if released, false if not owned or expired
     */
    releaseLock(policyId: string, tenantId: string, lockId: string): Promise<boolean>;
    /**
     * Execute a function with a distributed policy lock
     *
     * @param policyId - Policy ID to lock
     * @param tenantId - Tenant ID
     * @param operation - Async function to execute while holding lock
     * @param options - Lock options
     * @returns Result of the operation
     * @throws Error if lock cannot be acquired
     */
    withPolicyLock<T>(policyId: string, tenantId: string, operation: () => Promise<T>, options?: PolicyLockOptions): Promise<T>;
    /**
     * Get a policy from distributed cache with version validation
     *
     * @param policyId - Policy ID
     * @param tenantId - Tenant ID
     * @param expectedCacheVersion - Optional expected version to validate
     * @returns Cached policy or null if not found/stale
     */
    get(policyId: string, tenantId: string, expectedCacheVersion?: number): Promise<{
        policy: Policy | null;
        cacheVersion: number;
        stale: boolean;
    }>;
    /**
     * Write a policy to distributed cache atomically with version increment
     * (Write-through caching)
     *
     * @param policy - Policy to cache
     * @param ttlMs - Cache TTL in milliseconds
     * @returns New cache version
     */
    set(policy: Policy, ttlMs?: number): Promise<number>;
    /**
     * Mark a policy as stale (2-phase invalidation step 1)
     * Call this BEFORE committing database changes
     *
     * @param policyId - Policy ID
     * @param tenantId - Tenant ID
     */
    markStale(policyId: string, tenantId: string): Promise<void>;
    /**
     * Invalidate a policy in distributed cache (2-phase invalidation step 2)
     * Call this AFTER database changes are committed
     *
     * @param policyId - Policy ID
     * @param tenantId - Tenant ID
     */
    invalidate(policyId: string, tenantId: string): Promise<void>;
    /**
     * Get the current cache version for a policy
     *
     * @param policyId - Policy ID
     * @param tenantId - Tenant ID
     * @returns Version info or null if not found
     */
    getVersionInfo(policyId: string, tenantId: string): Promise<PolicyVersionInfo | null>;
    /**
     * Clear all cache entries for a tenant
     *
     * @param tenantId - Tenant ID
     */
    clearTenantCache(tenantId: string): Promise<number>;
}
/**
 * Error thrown when policy lock acquisition fails
 */
export declare class PolicyLockError extends Error {
    readonly code = "POLICY_LOCK_ERROR";
    readonly policyId: string;
    readonly tenantId: string;
    constructor(message: string, policyId: string, tenantId: string);
}
/**
 * Error thrown when stale cache is detected
 */
export declare class StaleCacheError extends Error {
    readonly code = "STALE_CACHE_ERROR";
    readonly policyId: string;
    readonly tenantId: string;
    readonly expectedVersion: number;
    readonly actualVersion: number;
    constructor(message: string, policyId: string, tenantId: string, expectedVersion: number, actualVersion: number);
}
/**
 * Get the distributed policy cache singleton
 */
export declare function getDistributedPolicyCache(): DistributedPolicyCache;
/**
 * Execute an operation with a distributed policy lock
 *
 * @param policyId - Policy ID to lock
 * @param tenantId - Tenant ID
 * @param operation - Async function to execute while holding lock
 * @returns Result of the operation
 */
export declare function withPolicyLock<T>(policyId: string, tenantId: string, operation: () => Promise<T>): Promise<T>;
//# sourceMappingURL=distributed-cache.d.ts.map