import { __assign, __awaiter, __generator, __read } from "tslib";
import { createCategories } from "../ArticleCategories";
import { executeCloneArticleOperation } from "./Cloning";
import { executeConfigureArticlesOperation } from "./Configuration";
import { executeDeleteOperation } from "./Deletion";
import { executeCreateArticleOperation } from "./Creation";
import { executeRestoreOperation, executeRestoreSessionProviderOperation, } from "./Restoring";
import { fetchArticleData, fetchArticleInfo } from "./Util";
export var createPDMOperator = function (sourceId, productDataManager, articleQuery, scheduler) {
    var sessionOperator = productDataManager.is("SessionProvider")
        ? createSessionOperator(sourceId, productDataManager, articleQuery)
        : undefined;
    var is = function (name) {
        if (name === "sessionOperator") {
            return sessionOperator !== undefined;
        }
        return false;
    };
    var addArticle = function (params) {
        return executeCreateArticleOperation(params, articleQuery, productDataManager).then(buildOperationResults);
    };
    var configureArticles = function (comIds, changes) {
        return executeConfigureArticlesOperation(comIds, changes, articleQuery, scheduler, productDataManager).then(buildOperationResults);
    };
    var deleteArticle = function (comId) {
        return executeDeleteOperation(comId, articleQuery, scheduler, productDataManager).then(buildOperationResults);
    };
    var cloneArticle = function (params) {
        return executeCloneArticleOperation(params, articleQuery, scheduler, productDataManager).then(buildOperationResults);
    };
    var restoreArticle = function (article) {
        return executeRestoreOperation(article, articleQuery, productDataManager).then(buildOperationResults);
    };
    var buildOperationResults = function (results) {
        return createPDMOperationResults(articleQuery, productDataManager, sourceId, results);
    };
    var executeArticlesOperation = function (operation) {
        return operation().then(function (operationResults) {
            return createPDMOperationResults(articleQuery, productDataManager, sourceId, operationResults);
        });
    };
    var getGfxRepresentation = function (comId, options) { return productDataManager.getGfxRepresentation(comId, options); };
    return __assign({ is: is,
        addArticle: addArticle,
        configureArticles: configureArticles,
        deleteArticle: deleteArticle,
        cloneArticle: cloneArticle,
        restoreArticle: restoreArticle,
        getGfxRepresentation: getGfxRepresentation,
        executeArticlesOperation: executeArticlesOperation }, sessionOperator);
};
var createSessionOperator = function (sourceId, productDataManager, articleQuery) {
    var save = function () { return productDataManager.save(); };
    var restore = function (data) {
        return executeRestoreSessionProviderOperation(data, productDataManager).then(function (results) {
            return createPDMOperationResults(articleQuery, productDataManager, sourceId, results);
        });
    };
    return {
        save: save,
        restore: restore,
    };
};
export var createPDMOperationResults = function (articleQuery, productDataManager, sourceId, results) {
    return Promise.all(results.map(function (result) {
        return createOperationResult(articleQuery, productDataManager, sourceId, result);
    })).then(function (results) {
        return results.filter(function (result) { return result !== false; });
    });
};
var createOperationResult = function (articleQuery, productDataManager, sourceId, operationResult) { return __awaiter(void 0, void 0, void 0, function () {
    return __generator(this, function (_a) {
        if (operationResult.type === "delete") {
            return [2 /*return*/, {
                    comId: operationResult.comId,
                    type: "delete",
                }];
        }
        if (operationResult.type === "configure") {
            return [2 /*return*/, createConfigureOperationResult(articleQuery, productDataManager, operationResult)];
        }
        return [2 /*return*/, createCreateOperationResult(articleQuery, productDataManager, sourceId, operationResult)];
    });
}); };
var createCreateOperationResult = function (articleQuery, productDataManager, sourceId, result) { return __awaiter(void 0, void 0, void 0, function () {
    var _a, configuration, articleId, dataCategories, properties, articleType, sourceData, info, children, sourcePlacement;
    return __generator(this, function (_b) {
        switch (_b.label) {
            case 0: return [4 /*yield*/, Promise.all([
                    productDataManager.getArticleConfiguration(result.comId),
                    productDataManager.getArticleID(result.comId),
                    result.categories !== undefined
                        ? Promise.resolve(result.categories)
                        : productDataManager.getArticleCategories(result.comId),
                    productDataManager.getArticlePropertyList(result.comId),
                    result.articleType !== undefined
                        ? Promise.resolve(result.articleType)
                        : productDataManager.getArticleType(result.comId),
                    productDataManager.getArticleCustomData === undefined
                        ? Promise.resolve(undefined)
                        : productDataManager.getArticleCustomData(result.comId),
                    fetchArticleInfo(productDataManager, result.comId, undefined),
                    result.children !== undefined
                        ? Promise.resolve(result.children)
                        : productDataManager.getSubArticleIDs(result.comId),
                    productDataManager.getArticlePlacement(result.comId),
                ])];
            case 1:
                _a = __read.apply(void 0, [_b.sent(), 9]), configuration = _a[0], articleId = _a[1], dataCategories = _a[2], properties = _a[3], articleType = _a[4], sourceData = _a[5], info = _a[6], children = _a[7], sourcePlacement = _a[8];
                return [2 /*return*/, {
                        type: "create",
                        articleType: articleType,
                        comId: result.comId,
                        source: sourceId,
                        categories: __assign(__assign({}, createCategories()), dataCategories),
                        properties: properties,
                        sourceData: sourceData || {},
                        articleNumber: result.articleNumber !== undefined
                            ? result.articleNumber
                            : {
                                baseArticleNumber: articleId,
                            },
                        placement: result.placement,
                        sourcePlacement: result.placement === undefined ? sourcePlacement : undefined,
                        parent: result.parent,
                        children: children,
                        info: info,
                        configuration: configuration,
                        articleId: articleId,
                        data: result.data,
                        gfxId: result.gfxId,
                    }];
        }
    });
}); };
var createConfigureOperationResult = function (articleQuery, productDataManager, operation) { return __awaiter(void 0, void 0, void 0, function () {
    var article, configuration, changes, _a, articleData, info;
    return __generator(this, function (_b) {
        switch (_b.label) {
            case 0:
                article = articleQuery.getArticleByComId(operation.comId);
                return [4 /*yield*/, productDataManager.getArticleConfiguration(operation.comId)];
            case 1:
                configuration = _b.sent();
                changes = Object.getOwnPropertyNames(configuration).filter(function (prop) { return article.configuration[prop] !== configuration[prop]; });
                if (changes.length === 0) {
                    return [2 /*return*/, false];
                }
                return [4 /*yield*/, Promise.all([
                        fetchArticleData(productDataManager, operation.comId),
                        fetchArticleInfo(productDataManager, operation.comId, article.info),
                    ])];
            case 2:
                _a = __read.apply(void 0, [_b.sent(), 2]), articleData = _a[0], info = _a[1];
                return [2 /*return*/, {
                        type: "change",
                        comId: operation.comId,
                        configuration: configuration,
                        categories: __assign(__assign({}, createCategories()), articleData.categories),
                        sourceData: articleData.sourceData,
                        properties: articleData.properties,
                        info: info,
                        articleId: articleData.articleId,
                        children: articleData.subArticles,
                    }];
        }
    });
}); };
