// SPDX-License-Identifier: Apache-2.0
// Copyright 2024-2026 Vorion LLC
/**
 * Shared mock Redis factory for security module tests.
 *
 * Mirrors the ioredis API surface used across brute-force, key-rotation,
 * secrets-rotation, session-store, and revocation-check modules.
 */
import { vi } from 'vitest';
export function createMockRedis() {
    const store = new Map();
    const mock = {
        // String operations
        get: vi.fn().mockImplementation((key) => Promise.resolve(store.get(key) ?? null)),
        set: vi.fn().mockImplementation((key, value) => { store.set(key, value); return Promise.resolve('OK'); }),
        setex: vi.fn().mockImplementation((key, _ttl, value) => { store.set(key, value); return Promise.resolve('OK'); }),
        del: vi.fn().mockImplementation((...keys) => { let c = 0; for (const k of keys) {
            if (store.delete(k))
                c++;
        } return Promise.resolve(c); }),
        incr: vi.fn().mockImplementation((key) => { const v = (Number(store.get(key)) || 0) + 1; store.set(key, String(v)); return Promise.resolve(v); }),
        expire: vi.fn().mockResolvedValue(1),
        ttl: vi.fn().mockResolvedValue(-1),
        exists: vi.fn().mockImplementation((key) => Promise.resolve(store.has(key) ? 1 : 0)),
        // Sorted set operations
        zadd: vi.fn().mockResolvedValue(1),
        zrangebyscore: vi.fn().mockResolvedValue([]),
        zremrangebyscore: vi.fn().mockResolvedValue(0),
        zcard: vi.fn().mockResolvedValue(0),
        zrevrange: vi.fn().mockResolvedValue([]),
        // Set operations
        sadd: vi.fn().mockResolvedValue(1),
        smembers: vi.fn().mockResolvedValue([]),
        srem: vi.fn().mockResolvedValue(1),
        // Hash operations
        hset: vi.fn().mockResolvedValue(1),
        hget: vi.fn().mockResolvedValue(null),
        hgetall: vi.fn().mockResolvedValue({}),
        hdel: vi.fn().mockResolvedValue(1),
        // Scan / Keys
        scan: vi.fn().mockResolvedValue(['0', []]),
        keys: vi.fn().mockImplementation((pattern) => {
            const prefix = pattern.replace('*', '');
            const matching = [...store.keys()].filter(k => k.startsWith(prefix));
            return Promise.resolve(matching);
        }),
        // Pub/Sub
        subscribe: vi.fn().mockResolvedValue(undefined),
        unsubscribe: vi.fn().mockResolvedValue(undefined),
        publish: vi.fn().mockResolvedValue(1),
        on: vi.fn(),
        duplicate: vi.fn(),
        quit: vi.fn().mockResolvedValue('OK'),
        // Utility
        _store: store,
        resetAll() {
            store.clear();
            Object.values(mock).forEach((v) => {
                if (typeof v === 'function' && 'mockClear' in v) {
                    v.mockClear();
                }
            });
        },
    };
    // duplicate() returns a fresh copy (used for pub/sub subscriber)
    mock.duplicate.mockReturnValue(mock);
    return mock;
}
//# sourceMappingURL=mock-redis.js.map