import { Cancellation } from "@intelligentgraphics/ig.utilities";
export const createConfigurationServiceOperator = (sourceId, configurationService, articleQuery, scheduler) => {
    const sessionOperator = createSessionOperator(sourceId, configurationService, articleQuery);
    const is = (name) => name === "sessionOperator" && sessionOperator !== undefined;
    const addArticle = (params) => {
        if (params.gfxId !== undefined) {
            throw new Error(`Received a gfxId as a parameter for article creation. This is not supported for configuration services!`);
        }
        return configurationService
            .createArticle(articleQuery, {
            articleNumber: params.articleNumber,
            data: params.data,
            initialPlacement: params.initialPlacement,
            initialConfiguration: params.initialConfiguration,
        })
            .then(results => createSessionOperationResults(results, sourceId));
    };
    const configureArticles = async (comIds, changes) => Promise.all(comIds.map(comId => scheduler
        .queueConfigureOperation(comId, changes, changes => configurationService.changeProperties(articleQuery, comId, changes))
        .catch(error => Cancellation.isCancelError(error)
        ? Promise.resolve([])
        : Promise.reject(error)))).then(results => createSessionOperationResults(results, sourceId));
    const deleteArticle = (comId) => scheduler.queueDeleteOperation(comId, () => configurationService
        .deleteArticle(articleQuery, comId)
        .then(results => createSessionOperationResults(results, sourceId)));
    const cloneArticle = (params) => scheduler.queueOperation(params.comId, () => configurationService
        .cloneArticle(articleQuery, params.comId)
        .then(results => createSessionOperationResults(results, sourceId)));
    const restoreArticle = (article) => {
        if (article.comId !== undefined &&
            articleQuery.getArticleByComId(article.comId) !== undefined) {
            return Promise.resolve([]);
        }
        return addArticle({
            initialConfiguration: article.configuration,
            initialPlacement: article.placement,
            articleNumber: article.articleNumber || {
                baseArticleNumber: article.articleId,
            },
            source: article.source,
        });
    };
    const getGfxRepresentation = (comId, options) => configurationService.getGfxRepresentation(articleQuery, comId, options);
    const executeArticlesOperation = (operation) => operation().then(results => createSessionOperationResults(results, sourceId));
    return {
        is,
        addArticle,
        configureArticles,
        deleteArticle,
        cloneArticle,
        restoreArticle,
        getGfxRepresentation,
        executeArticlesOperation,
        ...sessionOperator,
    };
};
const createSessionOperator = (sourceId, configurationService, articleQuery) => {
    if (!configurationService.is("sessionService")) {
        return;
    }
    return {
        save: () => configurationService.save(articleQuery),
        restore: (data) => configurationService
            .restore(articleQuery, data)
            .then(results => createSessionOperationResults(results, sourceId)),
    };
};
const createSessionOperationResults = (results, sourceId) => {
    const output = [];
    for (const result of results) {
        if (Array.isArray(result)) {
            output.push(...createSessionOperationResults(result, sourceId));
            continue;
        }
        output.push(createOperationResult(result, sourceId));
    }
    return output;
};
const createOperationResult = (result, sourceId) => {
    if (result.type === "create") {
        return {
            ...result,
            source: sourceId,
            gfxId: undefined,
        };
    }
    return result;
};
