"use strict";
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TrackingEmitter = exports.withCancellation = exports.getError = exports.getErrorMessage = exports.delay = exports.List = void 0;
const dev_tunnels_ssh_1 = require("@microsoft/dev-tunnels-ssh");
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
class List {
    static groupBy(list, keyGetter) {
        const map = new Map();
        list.forEach((item) => {
            const key = keyGetter(item);
            const collection = map.get(key);
            if (!collection) {
                map.set(key, [item]);
            }
            else {
                collection.push(item);
            }
        });
        return map;
    }
}
exports.List = List;
/**
 * Resolves the promise after {@link milliseconds} have passed, or reject if {@link cancellation} is canceled.
 */
function delay(milliseconds, cancellation) {
    return new Promise((resolve, reject) => {
        let cancellationDisposable;
        let timeout = undefined;
        if (cancellation) {
            if (cancellation.isCancellationRequested) {
                reject(new dev_tunnels_ssh_1.CancellationError());
                return;
            }
            cancellationDisposable = cancellation.onCancellationRequested(() => {
                if (timeout) {
                    clearTimeout(timeout);
                }
                cancellationDisposable === null || cancellationDisposable === void 0 ? void 0 : cancellationDisposable.dispose();
                reject(new dev_tunnels_ssh_1.CancellationError());
            });
        }
        timeout = setTimeout(() => {
            cancellationDisposable === null || cancellationDisposable === void 0 ? void 0 : cancellationDisposable.dispose();
            resolve();
        }, milliseconds);
    });
}
exports.delay = delay;
/**
 * Gets the error message.
 */
function getErrorMessage(e) {
    var _a;
    return String((_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : e);
}
exports.getErrorMessage = getErrorMessage;
/**
 * Wraps e in Error object if e is not Error. If e is Error, returns e as is.
 */
function getError(e, messagePrefix) {
    return e instanceof Error ? e : new Error(`${messagePrefix !== null && messagePrefix !== void 0 ? messagePrefix : ''}${e}`);
}
exports.getError = getError;
/**
 * Races a promise and cancellation.
 */
function withCancellation(promise, cancellation) {
    if (!cancellation) {
        return promise;
    }
    return Promise.race([
        promise,
        new Promise((resolve, reject) => {
            if (cancellation.isCancellationRequested) {
                reject(new dev_tunnels_ssh_1.CancellationError());
            }
            else {
                cancellation.onCancellationRequested(() => {
                    reject(new dev_tunnels_ssh_1.CancellationError());
                });
            }
        }),
    ]);
}
exports.withCancellation = withCancellation;
/**
 * Tracking event emitter.
 */
class TrackingEmitter extends vscode_jsonrpc_1.Emitter {
    constructor() {
        super({
            onFirstListenerAdd: () => this.subscribed = true,
            onLastListenerRemove: () => this.subscribed = false,
        });
        this.subscribed = false;
    }
    /**
     * A value indicating whether there event handlers subscribed to the event emitter.
     */
    get isSubscribed() {
        return this.subscribed;
    }
}
exports.TrackingEmitter = TrackingEmitter;
//# sourceMappingURL=https://main.vscode-cdn.net/sourcemaps/6a44c352bd24569c417e530095901b649960f9f8/node_modules/@microsoft/dev-tunnels-connections/utils.js.map