"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var igd_core_1 = require("@intelligentgraphics/igd.core");
exports.createCatalogFetcher = function (session, igxrLoader, language) {
    var cache = new Map();
    var createOperation = function (createIdentifier, fetch) { return function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        return executeOperation(createIdentifier, fetch, args);
    }; };
    var executeOperation = function (createIdentifier, executeOperation, args) {
        var identifier = createIdentifier.apply(void 0, tslib_1.__spread(args));
        var cachedValued = cache.get(identifier);
        if (cachedValued !== undefined) {
            return Promise.resolve(cachedValued);
        }
        var fetchResult = executeOperation.apply(void 0, tslib_1.__spread(args));
        cache.set(identifier, fetchResult);
        if (typeof fetchResult === "object" && "then" in fetchResult) {
            var fetchResultPromise = fetchResult;
            return fetchResultPromise
                .then(function (result) {
                cache.set(identifier, result);
                return result;
            })
                .catch(function (err) {
                cache.delete(identifier);
                return Promise.reject(err);
            });
        }
        return Promise.resolve(fetchResult);
    };
    var getCatalogManager = function (catalogId) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
        var catalogManager;
        return tslib_1.__generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    catalogManager = session.getCatalogManagerForSourceId(catalogId);
                    if (catalogManager !== undefined) {
                        return [2 /*return*/, catalogManager];
                    }
                    if (igxrLoader === undefined) {
                        throw new Error("The catalog \"" + catalogId + "\" is not yet registered, and no igxr loader was provided. The catalog can not be automatically registered.");
                    }
                    return [4 /*yield*/, igxrLoader.addCatalogToSession(catalogId, session)];
                case 1:
                    _a.sent();
                    catalogManager = session.getCatalogManagerForSourceId(catalogId);
                    if (catalogManager === undefined) {
                        throw new Error("No catalogmanager is available for source \"" + catalogId + "\" even after registering the catalog");
                    }
                    return [2 /*return*/, catalogManager];
            }
        });
    }); };
    var getFolder = createOperation(function (path) { return "folder_" + path.join(":"); }, function (_a) {
        var _b = tslib_1.__read(_a), catalogId = _b[0], path = _b.slice(1);
        return tslib_1.__awaiter(void 0, void 0, void 0, function () {
            var catalogManager, folder;
            return tslib_1.__generator(this, function (_c) {
                switch (_c.label) {
                    case 0: return [4 /*yield*/, getCatalogManager(catalogId)];
                    case 1:
                        catalogManager = _c.sent();
                        return [4 /*yield*/, catalogManager.getFolder(path[path.length - 1])];
                    case 2:
                        folder = _c.sent();
                        if (folder === undefined) {
                            throw new Error("Could not get folder for folder id \"" + path[path.length - 1] + "\" inside \"" + catalogId + "\"");
                        }
                        return [2 /*return*/, folder];
                }
            });
        });
    });
    // const getArticle = createOperation(
    // 	(path: string[]) => "article_" + path.join(":"),
    // 	async ([catalogId, ...path]: string[]) => {
    // 		const catalogManager = await getCatalogManager(catalogId);
    // 		const article = await catalogManager.getArticle(
    // 			path[path.length - 1],
    // 		);
    // 		if (article === undefined) {
    // 			throw new Error(
    // 				`Could not get article for article id "${
    // 					path[path.length - 1]
    // 				}" inside "${catalogId}"`,
    // 			);
    // 		}
    // 		return article;
    // 	},
    // );
    // const getSet = createOperation(
    // 	(path: string[]) => "set" + path.join(":"),
    // 	async ([catalogId, ...path]: string[]) => {
    // 		const catalogManager = await getCatalogManager(catalogId);
    // 		const set = await catalogManager.getSet(path[path.length - 1]);
    // 		if (set === undefined) {
    // 			throw new Error(
    // 				`Could not get set for set id "${
    // 					path[path.length - 1]
    // 				}" inside "${catalogId}"`,
    // 			);
    // 		}
    // 		return set;
    // 	},
    // );
    var getAddables = createOperation(function (path, baseArticleNumber) {
        return "addables_" + path.join(":") + "_" + baseArticleNumber;
    }, function (_a, baseArticleNumber) {
        var _b = tslib_1.__read(_a, 1), catalogId = _b[0];
        return tslib_1.__awaiter(void 0, void 0, void 0, function () {
            var catalogManager, addables;
            return tslib_1.__generator(this, function (_c) {
                switch (_c.label) {
                    case 0: return [4 /*yield*/, getCatalogManager(catalogId)];
                    case 1:
                        catalogManager = _c.sent();
                        return [4 /*yield*/, catalogManager.getAddables(baseArticleNumber)];
                    case 2:
                        addables = _c.sent();
                        return [2 /*return*/, addables];
                }
            });
        });
    });
    var getCatalog = function (_a) {
        var _b = tslib_1.__read(_a, 1), catalogId = _b[0];
        if (igxrLoader === undefined) {
            return Promise.reject(new Error("Could not retrieve informations for catalog \"" + catalogId + "\", because no igxr loader was provided."));
        }
        var catalog = igxrLoader.getCatalogInfo(catalogId, language);
        if (catalog === undefined) {
            return Promise.reject(new Error("Could not find informations for catalog \"" + catalogId + "\""));
        }
        return Promise.resolve({
            ID: catalogId,
            ManufacturerName: catalog.ManufacturerName,
            CatalogName: catalog.CatalogName,
            Type: igd_core_1.IGXA.EItemType.Catalog,
            Caption: catalog.CatalogName,
        });
    };
    var getPathContent = createOperation(function (path) { return "path_content_" + path.join(":"); }, function (path) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
        var _a, catalogId, inCatalogPath, catalogManager, items, content;
        return tslib_1.__generator(this, function (_b) {
            switch (_b.label) {
                case 0:
                    if (path.length === 0) {
                        if (igxrLoader === undefined) {
                            throw new Error("Can not retrieve a list of catalogs, because no igxr loader was provided");
                        }
                        return [2 /*return*/, igxrLoader
                                .getCatalogList(language)
                                .filter(function (catalog) { return !catalog.Hidden; })
                                .map(function (catalog) { return ({
                                Type: igd_core_1.IGXA.EItemType.Catalog,
                                ID: catalog.SourceId,
                                ManufacturerName: catalog.ManufacturerName,
                                CatalogName: catalog.CatalogName,
                                Image: catalog.Image,
                                Caption: catalog.CatalogName,
                            }); })];
                    }
                    _a = tslib_1.__read(path), catalogId = _a[0], inCatalogPath = _a.slice(1);
                    return [4 /*yield*/, getCatalogManager(catalogId)];
                case 1:
                    catalogManager = _b.sent();
                    items = [];
                    return [4 /*yield*/, catalogManager.getFolderContent(inCatalogPath[inCatalogPath.length - 1])];
                case 2:
                    content = _b.sent();
                    return [2 /*return*/, tslib_1.__spread(items, content)];
            }
        });
    }); });
    var getPathEntries = function (path) {
        if (path.length === 0) {
            return Promise.resolve([]);
        }
        return Promise.all(path.map(function (pathEntry, index) {
            var itemPath = path.slice(0, index + 1);
            if (itemPath.length === 1) {
                return getCatalog(itemPath);
            }
            return getFolder(itemPath);
        }));
    };
    var getReadablePath = function (path) {
        return getPathEntries(path).then(function (entries) {
            return entries.map(function (entry) {
                if (entry.Type === igd_core_1.IGXA.EItemType.Catalog) {
                    return entry.CatalogName;
                }
                return igd_core_1.IGXA.extractLocalizedText(entry.Caption, language).join(" ");
            });
        });
    };
    var getCatalogWizard = function (path) {
        if (igxrLoader === undefined) {
            throw new Error("Can not retrieve a wizard for catalog \"" + path[0] + "\", because no igxr loader was provided.");
        }
        var wizard = igxrLoader.getWizard(path[0], language);
        if (wizard === undefined) {
            return Promise.resolve(undefined);
        }
        return Promise.resolve({
            Type: igd_core_1.IGXA.EItemType.Wizard,
            ID: path[0],
            Image: wizard.Image,
            Caption: wizard.Name || "Wizard",
        });
    };
    return {
        getFolder: getFolder,
        // getArticle,
        // getSet,
        getAddables: getAddables,
        getCatalog: getCatalog,
        getPathContent: getPathContent,
        getPathEntries: getPathEntries,
        getReadablePath: getReadablePath,
        getCatalogWizard: getCatalogWizard,
    };
};
