/**
 * Redis Cluster Manager for Vorion Security Platform
 *
 * Provides production-ready Redis Cluster support with:
 * - Cluster connection with automatic node discovery
 * - Consistent hashing for key distribution
 * - Automatic failover handling with Sentinel support
 * - Read replicas for read scaling
 * - Connection health monitoring
 * - MOVED/ASK redirection handling
 * - Pipeline support across slots
 * - Pub/Sub with cluster awareness
 * - Comprehensive metrics
 *
 * @packageDocumentation
 * @module @vorionsys/common/redis-cluster
 */
import { Cluster } from 'ioredis';
import { EventEmitter } from 'events';
import { Counter, Gauge, Histogram } from 'prom-client';
/**
 * Redis Cluster node configuration
 */
export interface RedisClusterNode {
    /** Host address of the Redis node */
    host: string;
    /** Port number of the Redis node */
    port: number;
}
/**
 * NAT mapping for nodes behind NAT/load balancers
 */
export interface NatMapping {
    /** External host address */
    host: string;
    /** External port number */
    port: number;
}
/**
 * Redis Cluster configuration
 */
export interface RedisClusterConfig {
    /** Initial seed nodes for cluster discovery */
    nodes: RedisClusterNode[];
    /** Optional password for authentication */
    password?: string;
    /** Enable read replicas for read scaling (default: true) */
    enableReadReplicas?: boolean;
    /** Maximum number of MOVED/ASK redirections (default: 16) */
    maxRedirections?: number;
    /** Delay between retry attempts in ms (default: 100) */
    retryDelayMs?: number;
    /** NAT mapping for nodes behind NAT/load balancers */
    natMap?: Record<string, NatMapping>;
    /** Connection timeout in ms (default: 10000) */
    connectTimeoutMs?: number;
    /** Command timeout in ms (default: 5000) */
    commandTimeoutMs?: number;
    /** Enable TLS/SSL (default: false) */
    enableTls?: boolean;
    /** TLS options when enableTls is true */
    tlsOptions?: {
        ca?: string | Buffer;
        cert?: string | Buffer;
        key?: string | Buffer;
        rejectUnauthorized?: boolean;
    };
    /** Key prefix for all operations (default: 'vorion:') */
    keyPrefix?: string;
    /** Enable lazy connect (default: false) */
    lazyConnect?: boolean;
    /** Retry strategy configuration */
    retryStrategy?: {
        /** Maximum retry attempts (default: 10) */
        maxAttempts?: number;
        /** Base delay for exponential backoff in ms (default: 100) */
        baseDelayMs?: number;
        /** Maximum delay between retries in ms (default: 3000) */
        maxDelayMs?: number;
    };
    /** Cluster slots refresh interval in ms (default: 5000) */
    slotsRefreshIntervalMs?: number;
    /** Enable offline queue (default: true) */
    enableOfflineQueue?: boolean;
    /** Enable ready check (default: true) */
    enableReadyCheck?: boolean;
    /** Scale reads using (default: 'slave') - 'master' | 'slave' | 'all' */
    scaleReads?: 'master' | 'slave' | 'all';
}
/**
 * Redis Cluster node health status
 */
export interface NodeHealthStatus {
    /** Node address (host:port) */
    address: string;
    /** Whether the node is healthy */
    healthy: boolean;
    /** Role: master or slave */
    role: 'master' | 'slave' | 'unknown';
    /** Latency in ms (if healthy) */
    latencyMs?: number;
    /** Error message (if unhealthy) */
    error?: string;
    /** Slots served by this node (for masters) */
    slots?: number[];
    /** Number of connected replicas (for masters) */
    replicaCount?: number;
    /** Master address (for slaves) */
    masterAddress?: string;
}
/**
 * Cluster health status
 */
export interface ClusterHealthStatus {
    /** Whether the cluster is healthy */
    healthy: boolean;
    /** Cluster state: 'ok' | 'fail' */
    clusterState: string;
    /** Total number of nodes */
    nodeCount: number;
    /** Number of healthy nodes */
    healthyNodeCount: number;
    /** Number of master nodes */
    masterCount: number;
    /** Number of slave nodes */
    slaveCount: number;
    /** Slot coverage percentage */
    slotCoverage: number;
    /** Individual node health */
    nodes: NodeHealthStatus[];
    /** Any cluster-level error */
    error?: string;
}
/**
 * Failover event details
 */
export interface FailoverEvent {
    /** Timestamp of the event */
    timestamp: Date;
    /** Type of failover event */
    type: 'node_failure' | 'node_recovery' | 'slot_migration' | 'master_promotion';
    /** Affected node address */
    nodeAddress: string;
    /** Previous state */
    previousState?: string;
    /** Current state */
    currentState?: string;
    /** Additional details */
    details?: Record<string, unknown>;
}
/**
 * Pipeline batch result
 */
export interface PipelineBatchResult<T> {
    /** Whether all operations succeeded */
    success: boolean;
    /** Results for each operation */
    results: Array<{
        success: boolean;
        result?: T;
        error?: Error;
    }>;
    /** Total execution time in ms */
    executionTimeMs: number;
}
/**
 * Pub/Sub message handler
 */
export type PubSubMessageHandler = (channel: string, message: string) => void | Promise<void>;
/**
 * Pub/Sub pattern message handler
 */
export type PubSubPatternHandler = (pattern: string, channel: string, message: string) => void | Promise<void>;
/**
 * Redis cluster connections per node
 */
declare const redisClusterConnectionsGauge: Gauge<"role" | "node">;
/**
 * Redis cluster operations per slot
 */
declare const redisClusterSlotOperationsTotal: Counter<"operation" | "slot_range">;
/**
 * Redis cluster failover events
 */
declare const redisClusterFailoverEventsTotal: Counter<"type">;
/**
 * Redis cluster latency by node
 */
declare const redisClusterNodeLatencySeconds: Histogram<"operation" | "node">;
/**
 * Redis cluster redirections
 */
declare const redisClusterRedirectionsTotal: Counter<"type">;
/**
 * Redis cluster slot coverage
 */
declare const redisClusterSlotCoverageGauge: Gauge<string>;
/**
 * Redis cluster healthy nodes
 */
declare const redisClusterHealthyNodesGauge: Gauge<"role">;
/**
 * Redis Cluster Manager for production deployments
 *
 * Provides comprehensive cluster management including:
 * - Automatic node discovery and slot routing
 * - Failover detection and handling
 * - Read replica support for scaling
 * - Health monitoring and metrics
 * - Pipeline operations across slots
 * - Pub/Sub with cluster awareness
 *
 * @example
 * ```typescript
 * const clusterManager = new RedisClusterManager({
 *   nodes: [
 *     { host: 'redis-1.example.com', port: 6379 },
 *     { host: 'redis-2.example.com', port: 6379 },
 *     { host: 'redis-3.example.com', port: 6379 },
 *   ],
 *   password: process.env.REDIS_PASSWORD,
 *   enableReadReplicas: true,
 * });
 *
 * await clusterManager.connect();
 *
 * // Basic operations
 * await clusterManager.set('user:123', JSON.stringify({ name: 'John' }));
 * const user = await clusterManager.get('user:123');
 *
 * // Pub/Sub
 * clusterManager.subscribe('events', (channel, message) => {
 *   console.log(`Received: ${message}`);
 * });
 *
 * // Health check
 * const health = await clusterManager.getClusterHealth();
 * console.log(`Cluster healthy: ${health.healthy}`);
 * ```
 */
export declare class RedisClusterManager extends EventEmitter {
    private cluster;
    private readonly config;
    private isConnected;
    private isConnecting;
    private healthCheckInterval;
    private slotsRefreshInterval;
    private failoverHistory;
    private readonly maxFailoverHistory;
    private subscriberClient;
    private subscriptions;
    private patternSubscriptions;
    private nodeConnections;
    constructor(config: RedisClusterConfig);
    /**
     * Build cluster options for ioredis
     */
    private buildClusterOptions;
    /**
     * Connect to the Redis cluster
     */
    connect(): Promise<void>;
    /**
     * Wait for cluster to be ready
     */
    private waitForReady;
    /**
     * Set up event handlers for the cluster
     */
    private setupEventHandlers;
    /**
     * Get node address string
     */
    private getNodeAddress;
    /**
     * Start health check interval
     */
    private startHealthCheck;
    /**
     * Start slots refresh monitoring
     */
    private startSlotsRefreshMonitoring;
    /**
     * Update health metrics
     */
    private updateHealthMetrics;
    /**
     * Record a failover event
     */
    private recordFailoverEvent;
    /**
     * Get the underlying cluster client
     */
    getClient(): Cluster;
    /**
     * Check if cluster is connected
     */
    isClusterConnected(): boolean;
    /**
     * Disconnect from the cluster
     */
    disconnect(): Promise<void>;
    /**
     * Get detailed cluster health status
     */
    getClusterHealth(): Promise<ClusterHealthStatus>;
    /**
     * Parse cluster state from CLUSTER INFO output
     */
    private parseClusterState;
    /**
     * Get health status of all nodes
     */
    private getNodesHealth;
    /**
     * Parse a node line from CLUSTER NODES output
     */
    private parseNodeLine;
    /**
     * Check health of a specific node
     */
    private checkNodeHealth;
    /**
     * Check if cluster is healthy (quick check)
     */
    isHealthy(): Promise<boolean>;
    /**
     * Get failover history
     */
    getFailoverHistory(): FailoverEvent[];
    /**
     * Get a value by key
     */
    get(key: string): Promise<string | null>;
    /**
     * Set a value with optional TTL
     */
    set(key: string, value: string, ttlSeconds?: number): Promise<'OK'>;
    /**
     * Delete a key
     */
    del(key: string): Promise<number>;
    /**
     * Check if key exists
     */
    exists(key: string): Promise<boolean>;
    /**
     * Set key expiration
     */
    expire(key: string, seconds: number): Promise<boolean>;
    /**
     * Get time to live for a key
     */
    ttl(key: string): Promise<number>;
    /**
     * Increment a key
     */
    incr(key: string): Promise<number>;
    /**
     * Increment by a value
     */
    incrby(key: string, increment: number): Promise<number>;
    /**
     * Get a hash field
     */
    hget(key: string, field: string): Promise<string | null>;
    /**
     * Set a hash field
     */
    hset(key: string, field: string, value: string): Promise<number>;
    /**
     * Get all hash fields
     */
    hgetall(key: string): Promise<Record<string, string>>;
    /**
     * Delete hash fields
     */
    hdel(key: string, ...fields: string[]): Promise<number>;
    /**
     * Push to list (left)
     */
    lpush(key: string, ...values: string[]): Promise<number>;
    /**
     * Push to list (right)
     */
    rpush(key: string, ...values: string[]): Promise<number>;
    /**
     * Pop from list (left)
     */
    lpop(key: string): Promise<string | null>;
    /**
     * Pop from list (right)
     */
    rpop(key: string): Promise<string | null>;
    /**
     * Get list range
     */
    lrange(key: string, start: number, stop: number): Promise<string[]>;
    /**
     * Add members to set
     */
    sadd(key: string, ...members: string[]): Promise<number>;
    /**
     * Remove members from set
     */
    srem(key: string, ...members: string[]): Promise<number>;
    /**
     * Check if member is in set
     */
    sismember(key: string, member: string): Promise<boolean>;
    /**
     * Get all set members
     */
    smembers(key: string): Promise<string[]>;
    /**
     * Add to sorted set
     */
    zadd(key: string, score: number, member: string): Promise<number>;
    /**
     * Get sorted set range by score
     */
    zrangebyscore(key: string, min: number | string, max: number | string, options?: {
        limit?: {
            offset: number;
            count: number;
        };
    }): Promise<string[]>;
    /**
     * Remove from sorted set by score range
     */
    zremrangebyscore(key: string, min: number | string, max: number | string): Promise<number>;
    /**
     * Execute a pipeline of operations
     *
     * Note: In a cluster, keys in a pipeline should ideally hash to the same slot.
     * Use hash tags like {user:123} to ensure related keys are on the same node.
     */
    pipeline<T = unknown>(operations: Array<{
        command: string;
        args: (string | number)[];
    }>): Promise<PipelineBatchResult<T>>;
    /**
     * Execute multiple get operations
     */
    mget(keys: string[]): Promise<(string | null)[]>;
    /**
     * Get or create subscriber client
     */
    private getSubscriberClient;
    /**
     * Subscribe to a channel
     */
    subscribe(channel: string, handler: PubSubMessageHandler): Promise<void>;
    /**
     * Unsubscribe from a channel
     */
    unsubscribe(channel: string, handler?: PubSubMessageHandler): Promise<void>;
    /**
     * Subscribe to a pattern
     */
    psubscribe(pattern: string, handler: PubSubPatternHandler): Promise<void>;
    /**
     * Unsubscribe from a pattern
     */
    punsubscribe(pattern: string, handler?: PubSubPatternHandler): Promise<void>;
    /**
     * Publish a message to a channel
     */
    publish(channel: string, message: string): Promise<number>;
    /**
     * Execute a Lua script
     */
    eval(script: string, numKeys: number, ...args: (string | number)[]): Promise<unknown>;
    /**
     * Execute a cached Lua script by SHA
     */
    evalsha(sha: string, numKeys: number, ...args: (string | number)[]): Promise<unknown>;
    /**
     * Load a Lua script and return its SHA
     */
    scriptLoad(script: string): Promise<string>;
    /**
     * Prefix a key with the configured prefix
     */
    private prefixKey;
    /**
     * Get the slot number for a key
     */
    getSlot(key: string): number;
    /**
     * Calculate slot for a key
     */
    private calculateSlot;
    /**
     * CRC16 implementation for Redis cluster slot calculation
     */
    private crc16;
    /**
     * Get slot range string for metrics
     */
    private getSlotRange;
    /**
     * Record operation metrics
     */
    private recordOperationMetrics;
    /**
     * Handle operation error
     */
    private handleOperationError;
    /**
     * Scan keys matching a pattern
     *
     * Note: In a cluster, this scans all nodes
     */
    scan(pattern: string, count?: number): Promise<string[]>;
    /**
     * Flush all keys (use with caution!)
     */
    flushall(): Promise<void>;
}
/**
 * Initialize the global Redis cluster manager
 */
export declare function initializeRedisCluster(config: RedisClusterConfig): RedisClusterManager;
/**
 * Get the global Redis cluster manager
 */
export declare function getRedisCluster(): RedisClusterManager;
/**
 * Check if Redis cluster is initialized
 */
export declare function isRedisClusterInitialized(): boolean;
/**
 * Close the global Redis cluster connection
 */
export declare function closeRedisCluster(): Promise<void>;
export { redisClusterConnectionsGauge, redisClusterSlotOperationsTotal, redisClusterFailoverEventsTotal, redisClusterNodeLatencySeconds, redisClusterRedirectionsTotal, redisClusterSlotCoverageGauge, redisClusterHealthyNodesGauge, };
//# sourceMappingURL=redis-cluster.d.ts.map