"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);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRelationChanges = exports.getEntityChanges = void 0;
var ramda_1 = require("ramda");
var mdm_sdk_1 = require("@reltio/mdm-sdk");
var attributesView_1 = require("../../../helpers/attributesView");
var common_1 = require("./common");
var getValues = function (attributes, attrType) {
    if ('newValue' in attributes || 'oldValue' in attributes) {
        var newValue = attributes.newValue, oldValue = attributes.oldValue, type_1 = attributes.type;
        var newAttrValues_1 = (0, ramda_1.pathOr)([], ['value', attrType.name])(newValue);
        var oldAttrValues_1 = (0, ramda_1.pathOr)([], ['value', attrType.name])(oldValue);
        var length_1 = Math.max(newAttrValues_1.length, oldAttrValues_1.length);
        return (0, ramda_1.times)(function (index) {
            var attributeValue = {
                newValue: newAttrValues_1[index],
                oldValue: oldAttrValues_1[index],
                type: type_1
            };
            return [{ value: attributeValue }];
        }, length_1);
    }
    var values = attributes[attrType.name];
    return values ? [values] : [];
};
var getAttributesList = function (metadata, attrTypes, attributes, level, isReferenceSubAttribute) {
    if (level === void 0) { level = 0; }
    if (isReferenceSubAttribute === void 0) { isReferenceSubAttribute = false; }
    return (0, ramda_1.flatten)(attrTypes
        .map(function (attrType) {
        return getValues(attributes, attrType).map(function (value) {
            return value.map(function (attributeValue) {
                return dcrAttributesFactory(metadata, attrType, attributeValue, level, isReferenceSubAttribute);
            });
        });
    })
        .filter((0, ramda_1.complement)(ramda_1.isEmpty)));
};
var getSimpleAttributeValue = function (attributeType, attributeValue) {
    var value = (0, mdm_sdk_1.isSpecialAttribute)(attributeType) ? attributeValue : attributeValue.value;
    return (0, ramda_1.is)(Object, value) ? value : { newValue: attributeValue, type: mdm_sdk_1.DCRTypes.INSERT_ATTRIBUTE };
};
var dcrAttributesFactory = function (metadata, attributeType, attributeValue, level, isReferenceSubAttribute) {
    switch (attributeType.type) {
        case mdm_sdk_1.DataTypes.TYPE_NESTED:
        case mdm_sdk_1.DataTypes.TYPE_IMAGE:
            return getNestedAttributeChange(metadata, attributeType, attributeValue, level);
        case mdm_sdk_1.DataTypes.TYPE_REFERENCE:
            return getReferenceAttributeChange(metadata, attributeType, attributeValue, level);
        default: {
            var value = getSimpleAttributeValue(attributeType, attributeValue);
            return getSimpleAttributeChange(attributeType, value, level, isReferenceSubAttribute);
        }
    }
};
var extractLineIds = function (attributeValue) {
    var _a, _b;
    var lineIds = (_b = (_a = attributeValue === null || attributeValue === void 0 ? void 0 : attributeValue.value) === null || _a === void 0 ? void 0 : _a.newValue) === null || _b === void 0 ? void 0 : _b.lineIds;
    return Array.isArray(lineIds) ? lineIds : attributeValue.lineIds;
};
var getNestedAttributeChange = function (metadata, attributeType, attributeValue, level) {
    var attributeTypeList = (0, mdm_sdk_1.getAttributeTypeSubAttributes)({}, attributeType);
    var label = (0, mdm_sdk_1.getLabel)((attributeType === null || attributeType === void 0 ? void 0 : attributeType.label) || (attributeType === null || attributeType === void 0 ? void 0 : attributeType.name));
    var lineIds = extractLineIds(attributeValue);
    return [
        { level: level, label: label, attributeType: attributeType, attributeValue: attributeValue, lineIds: lineIds },
        getAttributesList(metadata, attributeTypeList, attributeValue.value, level + 1)
    ];
};
var getReferenceAttributeChange = function (metadata, attributeType, attributeValue, level) {
    var attributeTypeList = (0, mdm_sdk_1.getAttributeTypeSubAttributes)(metadata, attributeType);
    var label = (attributeType === null || attributeType === void 0 ? void 0 : attributeType.label) || (attributeType === null || attributeType === void 0 ? void 0 : attributeType.name);
    var lineIds = extractLineIds(attributeValue);
    return [
        { level: level, label: label, attributeType: attributeType, attributeValue: attributeValue, lineIds: lineIds },
        getAttributesList(metadata, attributeTypeList, attributeValue.value, level + 1, true)
    ];
};
var getDiffParameters = function (_a) {
    var newValue = _a.newValue, oldValue = _a.oldValue, type = _a.type, newPinOrIgnoreValue = _a.newPinOrIgnoreValue;
    return type === mdm_sdk_1.DCRTypes.UPDATE_ATTRIBUTE
        ? { type: type, newValue: newValue, oldValue: oldValue, newPinOrIgnoreValue: newPinOrIgnoreValue }
        : { type: type, newValue: oldValue || newValue, newPinOrIgnoreValue: newPinOrIgnoreValue };
};
var getSimpleAttributeChange = function (attributeType, attributeValue, level, isReferenceSubAttribute) {
    if (isReferenceSubAttribute === void 0) { isReferenceSubAttribute = false; }
    var _a = getDiffParameters(attributeValue), newValue = _a.newValue, oldValue = _a.oldValue, type = _a.type, newPinOrIgnoreValue = _a.newPinOrIgnoreValue;
    var operation = (0, common_1.getOperationType)(type, newPinOrIgnoreValue);
    var label = (attributeType === null || attributeType === void 0 ? void 0 : attributeType.label) || (attributeType === null || attributeType === void 0 ? void 0 : attributeType.name);
    return {
        attributeType: attributeType,
        newValue: newValue,
        oldValue: oldValue,
        operation: operation,
        label: label,
        level: level,
        isReferenceSubAttribute: isReferenceSubAttribute
    };
};
exports.getEntityChanges = (0, ramda_1.curry)(function (metadata, entityInfo, changes) {
    var attrTypes = (0, attributesView_1.getFilteredAttrTypes)(metadata, entityInfo.type, [], []);
    return getAttributesList(metadata, attrTypes, changes);
});
exports.getRelationChanges = (0, ramda_1.curry)(function (metadata, relationInfo, changes, changeType, relationChangeLineIds) {
    var addRelationOperationIfNeeded = function (changes, changeType) {
        if (changeType === mdm_sdk_1.DCRTypes.CREATE_RELATIONSHIP || (0, mdm_sdk_1.isEmptyValue)(changes)) {
            var operation = (0, common_1.getOperationType)(changeType);
            return operation ? { operation: operation } : {};
        }
        return {};
    };
    var relationType = (0, mdm_sdk_1.getRelationType)(metadata, relationInfo.type);
    var attrTypes = (0, mdm_sdk_1.getRelationAttributesList)(metadata, relationInfo.type);
    var lineIds = changeType === mdm_sdk_1.DCRTypes.CREATE_RELATIONSHIP || changeType === mdm_sdk_1.DCRTypes.DELETE_RELATIONSHIP
        ? (changes === null || changes === void 0 ? void 0 : changes.lineIds) || relationChangeLineIds
        : undefined;
    return (0, ramda_1.flatten)([
        __assign({ level: 1, label: (0, ramda_1.propOr)('', 'label', relationType), attributeType: null, relationType: relationType, attributeValue: __assign(__assign({}, relationInfo), changes), lineIds: lineIds }, addRelationOperationIfNeeded(changes, changeType)),
        getAttributesList(metadata, attrTypes, changes, 2)
    ]);
});
