"use strict";
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.prepareChangesList = void 0;
var mdm_sdk_1 = require("@reltio/mdm-sdk");
var common_1 = require("../../helpers/common");
var helpers_1 = require("./helpers");
var getImageOperation = function (diff) {
    var _a;
    var innerChange = (_a = diff.attributeValue) === null || _a === void 0 ? void 0 : _a.value;
    return (innerChange === null || innerChange === void 0 ? void 0 : innerChange.type) ? (0, common_1.getOperationType)(innerChange.type) : undefined;
};
var filterImageSubAttributes = function (rawChangesList) {
    var filtered = [];
    var skipBelowLevel = null;
    for (var _i = 0, rawChangesList_1 = rawChangesList; _i < rawChangesList_1.length; _i++) {
        var item = rawChangesList_1[_i];
        if (!(0, helpers_1.isDiffChange)(item)) {
            skipBelowLevel = null;
            filtered.push(item);
            continue;
        }
        var diff = item;
        if (skipBelowLevel !== null && diff.level > skipBelowLevel) {
            continue;
        }
        skipBelowLevel = null;
        if ((0, mdm_sdk_1.isImage)(diff.attributeType)) {
            skipBelowLevel = diff.level;
        }
        filtered.push(item);
    }
    return filtered;
};
var withImageOperation = function (items) {
    return items.map(function (item) {
        if (!(0, helpers_1.isDiffChange)(item) || !(0, mdm_sdk_1.isImage)(item.attributeType))
            return item;
        var operation = getImageOperation(item);
        return operation ? __assign(__assign({}, item), { operation: operation }) : item;
    });
};
var isSameGroup = function (a, b) {
    var _a, _b;
    return a.operation === mdm_sdk_1.DCROperationTypes.ADDED &&
        b.operation === mdm_sdk_1.DCROperationTypes.ADDED &&
        ((_a = a.attributeType) === null || _a === void 0 ? void 0 : _a.uri) === ((_b = b.attributeType) === null || _b === void 0 ? void 0 : _b.uri) &&
        a.level === b.level;
};
var canAddSameAttribute = function (attributeType) {
    var _a;
    if (!attributeType)
        return false;
    if (attributeType.singleValue)
        return false;
    if (((_a = attributeType.cardinality) === null || _a === void 0 ? void 0 : _a.maxValue) === 1)
        return false;
    if ((0, mdm_sdk_1.isRoleAttrType)(attributeType) || (0, mdm_sdk_1.isTagAttrType)(attributeType))
        return false;
    return true;
};
var withDisplayOptions = function (items) {
    return items.map(function (item, i) {
        if (!(0, helpers_1.isDiffChange)(item))
            return item;
        if (item.operation !== mdm_sdk_1.DCROperationTypes.ADDED) {
            return __assign(__assign({}, item), { displayOptions: {
                    showLabel: item.operation !== mdm_sdk_1.DCROperationTypes.EDITED,
                    showAddButton: false,
                    hasSameAttributeSiblings: false
                } });
        }
        var prev = items[i - 1];
        var next = items[i + 1];
        var hasPrevSibling = !!prev && (0, helpers_1.isDiffChange)(prev) && isSameGroup(prev, item);
        var hasNextSibling = !!next && (0, helpers_1.isDiffChange)(next) && isSameGroup(item, next);
        return __assign(__assign({}, item), { displayOptions: {
                showLabel: !hasPrevSibling,
                showAddButton: canAddSameAttribute(item.attributeType) && !hasNextSibling,
                hasSameAttributeSiblings: hasPrevSibling || hasNextSibling
            } });
    });
};
var truncateAtSegment = function (source, segment) {
    var index = source.indexOf(segment);
    return index >= 0 ? source.substring(0, index + segment.length) : undefined;
};
var findDescendantWithPath = function (items, fromIndex, parentLevel) {
    for (var j = fromIndex + 1; j < items.length; j++) {
        var next = items[j];
        if (!(0, helpers_1.isDiffChange)(next) || next.level <= parentLevel)
            break;
        if (next.attributePath)
            return next;
    }
    return undefined;
};
var deriveParentPath = function (descendant, name, instanceId) {
    var segment = "".concat(name, "/").concat(instanceId);
    var result = {};
    var attributePath = truncateAtSegment(descendant.attributePath, segment);
    if (attributePath) {
        result.attributePath = attributePath;
    }
    if (descendant.refAttributeType) {
        var refAttributeType = truncateAtSegment(descendant.refAttributeType, "/attributes/".concat(name));
        if (refAttributeType) {
            result.refAttributeType = refAttributeType;
        }
    }
    if (descendant.refObjectURI) {
        result.refObjectURI = descendant.refObjectURI;
    }
    return Object.keys(result).length > 0 ? result : null;
};
var extractPathFromInnerChange = function (attributeValue) {
    var inner = attributeValue === null || attributeValue === void 0 ? void 0 : attributeValue.value;
    if (!(inner === null || inner === void 0 ? void 0 : inner.attributePath))
        return null;
    return __assign(__assign({ attributePath: inner.attributePath }, (inner.refAttributeType && { refAttributeType: inner.refAttributeType })), (inner.refObjectURI && { refObjectURI: inner.refObjectURI }));
};
var fillParentPaths = function (items) {
    var _a, _b;
    var result = __spreadArray([], items, true);
    for (var index = result.length - 1; index >= 0; index--) {
        var item = result[index];
        if (!(0, helpers_1.isDiffChange)(item) || !(0, mdm_sdk_1.isComplexAttribute)(item.attributeType) || item.attributePath)
            continue;
        var innerPath = extractPathFromInnerChange(item.attributeValue);
        if (innerPath) {
            result[index] = __assign(__assign({}, item), innerPath);
            continue;
        }
        var name_1 = (_a = item.attributeType) === null || _a === void 0 ? void 0 : _a.name;
        var instanceId = (_b = item.attributeValue) === null || _b === void 0 ? void 0 : _b.id;
        if (!name_1 || !instanceId)
            continue;
        var descendant = findDescendantWithPath(result, index, item.level);
        if (!descendant)
            continue;
        var parentPath = deriveParentPath(descendant, name_1, instanceId);
        if (parentPath) {
            result[index] = __assign(__assign({}, item), parentPath);
        }
    }
    return result;
};
var prepareChangesList = function (rawChangesList) {
    var withPaths = fillParentPaths(rawChangesList);
    var filtered = filterImageSubAttributes(withPaths);
    var withOperations = withImageOperation(filtered);
    return withDisplayOptions(withOperations);
};
exports.prepareChangesList = prepareChangesList;
