/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';
var events_1 = require('events');
var assert_1 = require('assert');
var _gcsignals = require('../build/Release/gcsignals');
;
/**
 * Create a new GC signal. When being garbage collected the passed
 * value is stored for later consumption.
 */
exports.GCSignal = _gcsignals.GCSignal;
var _emitter = new events_1.EventEmitter();
/**
 * Consume ids of garbage collected signals.
 */
function consumeSignals() {
    var signals = Object.freeze(_gcsignals.consumeSignals());
    if (signals.length > 0) {
        // remove form list of active ids
        for (var _i = 0, signals_1 = signals; _i < signals_1.length; _i++) {
            var id = signals_1[_i];
            activeIds.delete(id);
        }
        // send event
        _emitter.emit('gc', signals);
    }
    return signals;
}
exports.consumeSignals = consumeSignals;
/**
 * Get called when any call to `consumeSignals` yielded in a result.
 */
function onDidGarbageCollectSignals(callback) {
    assert_1.ok(typeof callback === 'function');
    _emitter.addListener('gc', callback);
    return {
        dispose: function () {
            if (callback) {
                _emitter.removeListener('gc', callback);
                callback = null;
            }
        }
    };
}
exports.onDidGarbageCollectSignals = onDidGarbageCollectSignals;
// --- util
var activeSignals = new WeakMap();
var activeIds = new Set();
/**
 * Utility method to store a weak reference of an object
 * along with an identifier. The id will be used to track
 * garbage collection of the object.
 */
function trackGarbageCollection(obj, id) {
    assert_1.ok(typeof obj === 'object', 'obj must be an object');
    assert_1.ok(typeof id === 'number', 'id must be a number');
    assert_1.ok(!activeIds.has(id), "object-id (" + id + ") in use");
    activeIds.add(id);
    activeSignals.set(obj, new exports.GCSignal(id));
    return id;
}
exports.trackGarbageCollection = trackGarbageCollection;
