export class RedisIdempotencyStore {
    redis;
    ttlSeconds;
    prefix;
    constructor(redisClient, ttlSeconds = 86400, prefix = 'idempotency') {
        this.redis = redisClient;
        this.ttlSeconds = ttlSeconds;
        this.prefix = prefix;
    }
    getKey(idempotencyKey, tenant, route) {
        return `${this.prefix}:${tenant}:${route}:${idempotencyKey}`;
    }
    async get(key, tenant, route) {
        try {
            const redisKey = this.getKey(key, tenant, route);
            const data = await this.redis.get(redisKey);
            if (!data) {
                return null;
            }
            const parsed = JSON.parse(data);
            if (new Date(parsed.expiresAt) < new Date()) {
                await this.delete(key, tenant, route);
                return null;
            }
            return {
                ...parsed,
                createdAt: new Date(parsed.createdAt),
                expiresAt: new Date(parsed.expiresAt)
            };
        }
        catch (error) {
            console.error('Error getting idempotency key:', error);
            return null;
        }
    }
    async set(key, tenant, route, bodyHash, response) {
        try {
            const redisKey = this.getKey(key, tenant, route);
            const now = new Date();
            const expiresAt = new Date(now.getTime() + this.ttlSeconds * 1000);
            const data = {
                key,
                tenant,
                route,
                bodyHash,
                response: response.body,
                statusCode: response.statusCode,
                headers: response.headers || {},
                createdAt: now,
                expiresAt
            };
            await this.redis.setex(redisKey, this.ttlSeconds, JSON.stringify(data));
        }
        catch (error) {
            console.error('Error setting idempotency key:', error);
        }
    }
    async delete(key, tenant, route) {
        try {
            const redisKey = this.getKey(key, tenant, route);
            await this.redis.del(redisKey);
        }
        catch (error) {
            console.error('Error deleting idempotency key:', error);
        }
    }
    async cleanup() {
        try {
            console.log('Idempotency cleanup requested - Redis TTL handles expiration automatically');
        }
        catch (error) {
            console.error('Error during idempotency cleanup:', error);
        }
    }
}
export class InMemoryIdempotencyStore {
    store = new Map();
    ttlSeconds;
    constructor(ttlSeconds = 86400) {
        this.ttlSeconds = ttlSeconds;
    }
    getKey(idempotencyKey, tenant, route) {
        return `${tenant}:${route}:${idempotencyKey}`;
    }
    async get(key, tenant, route) {
        const storeKey = this.getKey(key, tenant, route);
        const data = this.store.get(storeKey);
        if (!data) {
            return null;
        }
        if (data.expiresAt < new Date()) {
            this.store.delete(storeKey);
            return null;
        }
        return data;
    }
    async set(key, tenant, route, bodyHash, response) {
        const storeKey = this.getKey(key, tenant, route);
        const now = new Date();
        const expiresAt = new Date(now.getTime() + this.ttlSeconds * 1000);
        const data = {
            key,
            tenant,
            route,
            bodyHash,
            response: response.body,
            statusCode: response.statusCode,
            headers: response.headers || {},
            createdAt: now,
            expiresAt
        };
        this.store.set(storeKey, data);
    }
    async delete(key, tenant, route) {
        const storeKey = this.getKey(key, tenant, route);
        this.store.delete(storeKey);
    }
    async cleanup() {
        const now = new Date();
        for (const [key, value] of this.store.entries()) {
            if (value.expiresAt < now) {
                this.store.delete(key);
            }
        }
    }
}
//# sourceMappingURL=IdempotencyStore.js.map