import { __awaiter, __generator, __values } from "tslib";
import BaseLogger from "./Logger";
var Logger = BaseLogger.createSubLogger("BackendManager");
export var createBackendManager = function (initialBackends) {
    if (initialBackends === void 0) { initialBackends = {}; }
    var backends = new Map();
    var backendCreators = new Map();
    var registerBackend = function (type, creator) {
        return backendCreators.set(type, creator);
    };
    var loadBackend = function (type) {
        if (!backends.has(type)) {
            return loadBackends([type]).then(function () { return backends.get(type); });
        }
        return Promise.resolve(backends.get(type));
    };
    var loadBackends = function (names) { return __awaiter(void 0, void 0, void 0, function () {
        var names_1, names_1_1, entry, loader, result, e_1_1;
        var e_1, _a;
        return __generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    _b.trys.push([0, 5, 6, 7]);
                    names_1 = __values(names), names_1_1 = names_1.next();
                    _b.label = 1;
                case 1:
                    if (!!names_1_1.done) return [3 /*break*/, 4];
                    entry = names_1_1.value;
                    if (backends.has(entry)) {
                        return [3 /*break*/, 3];
                    }
                    loader = backendCreators.get(entry);
                    if (!loader) {
                        throw new Error("Unkown backend type: " + entry);
                    }
                    return [4 /*yield*/, loader()];
                case 2:
                    result = _b.sent();
                    backends.set(entry, result);
                    _b.label = 3;
                case 3:
                    names_1_1 = names_1.next();
                    return [3 /*break*/, 1];
                case 4: return [3 /*break*/, 7];
                case 5:
                    e_1_1 = _b.sent();
                    e_1 = { error: e_1_1 };
                    return [3 /*break*/, 7];
                case 6:
                    try {
                        if (names_1_1 && !names_1_1.done && (_a = names_1.return)) _a.call(names_1);
                    }
                    finally { if (e_1) throw e_1.error; }
                    return [7 /*endfinally*/];
                case 7: return [2 /*return*/];
            }
        });
    }); };
    var getBackendForServerType = function (serverType) {
        if (backends.has(serverType)) {
            return backends.get(serverType);
        }
    };
    for (var serverType in initialBackends) {
        var value = initialBackends[serverType];
        registerBackend(serverType, value);
    }
    return {
        registerBackend: registerBackend,
        loadBackend: loadBackend,
        getBackendForServerType: getBackendForServerType,
    };
};
