"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var ETagCacheService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ETagCacheService = void 0;
const common_1 = require("@nestjs/common");
const crypto_1 = require("crypto");
let ETagCacheService = ETagCacheService_1 = class ETagCacheService {
    constructor() {
        this.logger = new common_1.Logger(ETagCacheService_1.name);
        this.cache = new Map();
        this.defaultTtl = 30 * 1000;
    }
    safeStringify(data) {
        const seen = new WeakSet();
        return JSON.stringify(data, (key, value) => {
            if (typeof value === 'object' && value !== null) {
                if (seen.has(value)) {
                    return '[Circular]';
                }
                seen.add(value);
            }
            if (typeof value === 'function' || typeof value === 'symbol') {
                return undefined;
            }
            return value;
        });
    }
    computeETag(data) {
        try {
            const jsonStr = this.safeStringify(data);
            if (!jsonStr) {
                return null;
            }
            return (0, crypto_1.createHash)('md5').update(jsonStr).digest('hex');
        }
        catch (err) {
            this.logger.warn(`Failed to compute ETag: ${err.message}`);
            return null;
        }
    }
    get(key, ttl = this.defaultTtl) {
        const entry = this.cache.get(key);
        if (!entry) {
            return null;
        }
        const now = Date.now();
        if (now - entry.timestamp > ttl) {
            this.cache.delete(key);
            return null;
        }
        return entry;
    }
    set(key, data) {
        const etag = this.computeETag(data);
        if (!etag) {
            return null;
        }
        const entry = {
            data,
            etag,
            timestamp: Date.now(),
        };
        this.cache.set(key, entry);
        return etag;
    }
    invalidate(key) {
        this.cache.delete(key);
    }
    invalidatePattern(pattern) {
        const regex = new RegExp(pattern);
        for (const key of this.cache.keys()) {
            if (regex.test(key)) {
                this.cache.delete(key);
            }
        }
    }
    clear() {
        this.cache.clear();
    }
};
exports.ETagCacheService = ETagCacheService;
exports.ETagCacheService = ETagCacheService = ETagCacheService_1 = __decorate([
    (0, common_1.Injectable)()
], ETagCacheService);
//# sourceMappingURL=etag-cache.service.js.map