import { __assign, __awaiter, __generator, __read, __spread, __values } from "tslib";
import { Cancellation } from "@intelligentgraphics/ig.utilities";
export var createConfigurationServiceOperator = function (sourceId, configurationService, articleQuery, scheduler) {
    var sessionOperator = createSessionOperator(sourceId, configurationService, articleQuery);
    var is = function (name) {
        return name === "sessionOperator" && sessionOperator !== undefined;
    };
    var addArticle = function (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(function (results) { return createSessionOperationResults(results, sourceId); });
    };
    var configureArticles = function (comIds, changes) { return __awaiter(void 0, void 0, void 0, function () {
        return __generator(this, function (_a) {
            return [2 /*return*/, Promise.all(comIds.map(function (comId) {
                    return scheduler
                        .queueConfigureOperation(comId, changes, function (changes) {
                        return configurationService.changeProperties(articleQuery, comId, changes);
                    })
                        .catch(function (error) {
                        return Cancellation.isCancelError(error)
                            ? Promise.resolve([])
                            : Promise.reject(error);
                    });
                })).then(function (results) { return createSessionOperationResults(results, sourceId); })];
        });
    }); };
    var deleteArticle = function (comId) {
        return scheduler.queueDeleteOperation(comId, function () {
            return configurationService
                .deleteArticle(articleQuery, comId)
                .then(function (results) {
                return createSessionOperationResults(results, sourceId);
            });
        });
    };
    var cloneArticle = function (params) {
        return scheduler.queueOperation(params.comId, function () {
            return configurationService
                .cloneArticle(articleQuery, params.comId)
                .then(function (results) {
                return createSessionOperationResults(results, sourceId);
            });
        });
    };
    var restoreArticle = function (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,
        });
    };
    var getGfxRepresentation = function (comId, options) {
        return configurationService.getGfxRepresentation(articleQuery, comId, options);
    };
    var executeArticlesOperation = function (operation) {
        return operation().then(function (results) {
            return createSessionOperationResults(results, sourceId);
        });
    };
    return __assign({ is: is,
        addArticle: addArticle,
        configureArticles: configureArticles,
        deleteArticle: deleteArticle,
        cloneArticle: cloneArticle,
        restoreArticle: restoreArticle,
        getGfxRepresentation: getGfxRepresentation,
        executeArticlesOperation: executeArticlesOperation }, sessionOperator);
};
var createSessionOperator = function (sourceId, configurationService, articleQuery) {
    if (!configurationService.is("sessionService")) {
        return;
    }
    return {
        save: function () { return configurationService.save(articleQuery); },
        restore: function (data) {
            return configurationService
                .restore(articleQuery, data)
                .then(function (results) {
                return createSessionOperationResults(results, sourceId);
            });
        },
    };
};
var createSessionOperationResults = function (results, sourceId) {
    var e_1, _a;
    var output = [];
    try {
        for (var results_1 = __values(results), results_1_1 = results_1.next(); !results_1_1.done; results_1_1 = results_1.next()) {
            var result = results_1_1.value;
            if (Array.isArray(result)) {
                output.push.apply(output, __spread(createSessionOperationResults(result, sourceId)));
                continue;
            }
            output.push(createOperationResult(result, sourceId));
        }
    }
    catch (e_1_1) { e_1 = { error: e_1_1 }; }
    finally {
        try {
            if (results_1_1 && !results_1_1.done && (_a = results_1.return)) _a.call(results_1);
        }
        finally { if (e_1) throw e_1.error; }
    }
    return output;
};
var createOperationResult = function (result, sourceId) {
    if (result.type === "create") {
        return __assign(__assign({}, result), { source: sourceId, gfxId: undefined });
    }
    return result;
};
