export const createServiceManager = (backendManager) => {
    const sources = new Map();
    const comIdMapping = new Map();
    const createSourceItemGetter = (name) => (sourceId) => getSourceItem(sourceId, name);
    const getSourceItem = (sourceId, name) => {
        if (!sources.has(sourceId)) {
            return undefined;
        }
        const sourceData = sources.get(sourceId);
        return sourceData[name];
    };
    const createSourceItemByComIdGetter = (name) => (comId) => {
        if (!comIdMapping.has(comId)) {
            return undefined;
        }
        const sourceId = comIdMapping.get(comId);
        return getSourceItem(sourceId, name);
    };
    const createSourceItemSetter = (name) => (sourceId, item) => {
        if (getSourceItem(sourceId, name) !== undefined) {
            return;
        }
        let sourceData = sources.get(sourceId);
        if (sourceData !== undefined) {
            sourceData[name] = item;
            return;
        }
        sourceData = {
            productDataManager: undefined,
            catalogManager: undefined,
            multiArticles: undefined,
            serverType: undefined,
            operator: undefined,
            configurationService: undefined,
            [name]: item,
        };
        sources.set(sourceId, sourceData);
    };
    const setArticleSource = (comId, sourceId) => comIdMapping.set(comId, sourceId);
    const deleteArticleSource = (comId) => comIdMapping.delete(comId);
    const getSourceBackend = (sourceId) => {
        const serverType = getSourceItem(sourceId, "serverType");
        if (serverType === undefined) {
            return undefined;
        }
        return backendManager.getBackendForServerType(serverType);
    };
    const getOperatorForComId = (comId) => {
        const sourceId = comIdMapping.get(comId);
        return getOperatorForSourceId(sourceId);
    };
    const getOperatorForSourceId = (sourceId) => {
        const operator = getSourceItem(sourceId, "operator");
        if (operator === undefined) {
            throw new Error(`No operator has been registered for sourceId "${sourceId}"`);
        }
        return operator;
    };
    const getRegisteredSourceIds = () => Array.from(sources.keys());
    const getRegisteredSourceIdsForServerType = (serverType) => {
        const sourceIds = [];
        for (const [sourceId, sourceData] of sources) {
            if (sourceData.serverType === serverType) {
                sourceIds.push(sourceId);
            }
        }
        return sourceIds;
    };
    return {
        getRegisteredSourceIds,
        getRegisteredSourceIdsForServerType,
        registerBackend: backendManager.registerBackend,
        loadBackend: backendManager.loadBackend,
        getBackendForServerType: backendManager.getBackendForServerType,
        deleteArticleSource,
        setArticleSource,
        setSourceServerType: createSourceItemSetter("serverType"),
        getSourceServerType: createSourceItemGetter("serverType"),
        getSourceBackend,
        registerCatalogManager: createSourceItemSetter("catalogManager"),
        getCatalogManagerForSourceId: createSourceItemGetter("catalogManager"),
        getCatalogManagerForComId: createSourceItemByComIdGetter("catalogManager"),
        registerProductDataManager: createSourceItemSetter("productDataManager"),
        getProductDataManagerForSourceId: createSourceItemGetter("productDataManager"),
        getProductDataManagerForComId: createSourceItemByComIdGetter("productDataManager"),
        registerMultiArticles: createSourceItemSetter("multiArticles"),
        getMultiArticlesForSourceId: createSourceItemGetter("multiArticles"),
        getMultiArticlesForComId: createSourceItemByComIdGetter("multiArticles"),
        registerOperator: createSourceItemSetter("operator"),
        getOperatorForComId,
        getOperatorForSourceId,
        getConfigurationServiceForComId: createSourceItemByComIdGetter("configurationService"),
        getConfigurationServiceForSourceId: createSourceItemGetter("configurationService"),
        registerConfigurationService: createSourceItemSetter("configurationService"),
    };
};
