"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MemberDefinitionMapper = void 0;
const string_format_1 = __importDefault(require("string-format"));
const base_1 = require("../contracts/base");
const data_type_1 = __importDefault(require("../contracts/base/data-type"));
const error_messages_1 = __importDefault(require("../error-messages"));
const guard_1 = __importDefault(require("../guard"));
const property_definition_resource_1 = require("../models/property-definition-resource");
const relation_definition_resource_1 = require("../models/relation-definition-resource");
const member_condition_mapper_1 = require("./member-condition-mapper");
const relation_cardinality_mapper_1 = require("./relation-cardinality-mapper");
const relation_role_mapper_1 = require("./relation-role-mapper");
class MemberDefinitionMapper {
    constructor(client) {
        guard_1.default.notNullOrUndefined(client, "client");
        this._client = client;
        this._memberConditionMapper = new member_condition_mapper_1.MemberConditionMapper(client);
    }
    //#region To SDK
    mapMemberDefinitionsAsync(memberDefinitionResources) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!memberDefinitionResources || memberDefinitionResources.length === 0)
                return [];
            const list = [];
            for (const memberDefinitionResource of memberDefinitionResources) {
                const memberDefinition = yield this.mapMemberDefinitionAsync(memberDefinitionResource);
                if (memberDefinition != null) {
                    list.push(memberDefinition);
                }
            }
            return list;
        });
    }
    mapMemberDefinitionAsync(resource) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!resource)
                return null;
            let definition;
            if (resource instanceof property_definition_resource_1.PropertyDefinitionResource) {
                definition = yield this.mapPropertyDefinitionAsync(resource);
            }
            else if (resource instanceof relation_definition_resource_1.RelationDefinitionResource) {
                definition = yield this.mapRelationDefinitionAsync(resource);
            }
            else {
                throw Error("Unknown property definition type.");
            }
            definition.conditions = yield this._memberConditionMapper.mapMemberConditionsAsync(resource.conditions);
            definition.isSecured = resource.isConditional != null ? resource.isSecured : false;
            definition.isSystemOwned = resource.isSystemOwned;
            definition.allowUpdates = resource.allowUpdates != null ? resource.allowUpdates : false;
            definition.labels = JSON.parse(JSON.stringify(resource.labels));
            definition.helpText = JSON.parse(JSON.stringify(resource.helpText));
            definition.canTriggerConditionalMembers = resource.canTriggerConditionalMembers;
            definition.canWrite = resource.canWrite;
            return definition;
        });
    }
    mapPropertyDefinitionAsync(resource) {
        return __awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
            guard_1.default.notNullOrUndefined(resource);
            const initObj = {
                boost: (_a = resource.boost) !== null && _a !== void 0 ? _a : false,
                includeInCompletion: (_b = resource.includeInCompletion) !== null && _b !== void 0 ? _b : false,
                includeInContent: (_c = resource.includeInContent) !== null && _c !== void 0 ? _c : false,
                indexed: (_d = resource.indexed) !== null && _d !== void 0 ? _d : false,
                isMultiLanguage: (_e = resource.isMultiLanguage) !== null && _e !== void 0 ? _e : false,
                isMandatory: (_f = resource.isMandatory) !== null && _f !== void 0 ? _f : false,
                isMultiValue: (_g = resource.isMultiValue) !== null && _g !== void 0 ? _g : false,
                isUnique: (_h = resource.isUnique) !== null && _h !== void 0 ? _h : false,
                canTriggerConditionalMembers: (_j = resource.canTriggerConditionalMembers) !== null && _j !== void 0 ? _j : false,
                canWrite: (_k = resource.canWrite) !== null && _k !== void 0 ? _k : false,
                ignoreOnExport: (_l = resource.ignoreOnExport) !== null && _l !== void 0 ? _l : false,
                storedInGraph: (_m = resource.storedInGraph) !== null && _m !== void 0 ? _m : false,
                conditionalValidation: resource.conditionalValidation,
            };
            switch (resource.type) {
                case data_type_1.default.Boolean:
                    return new base_1.BooleanPropertyDefinition(resource.name, Object.assign({}, initObj));
                case data_type_1.default.DateTime:
                    return new base_1.DateTimePropertyDefinition(resource.name, Object.assign({}, initObj));
                case data_type_1.default.DateTimeOffset:
                    return new base_1.DateTimeOffsetPropertyDefinition(resource.name, Object.assign({}, initObj));
                case data_type_1.default.Decimal:
                    return new base_1.DecimalPropertyDefinition(resource.name, Object.assign({}, initObj));
                case data_type_1.default.Integer:
                    return new base_1.IntegerPropertyDefinition(resource.name, Object.assign({}, initObj));
                case data_type_1.default.Json:
                    const jsonPropResource = resource;
                    return new base_1.JsonPropertyDefinition(resource.name, Object.assign(Object.assign({}, initObj), { contentType: jsonPropResource.contentType }));
                case data_type_1.default.Long:
                    return new base_1.LongPropertyDefinition(resource.name, Object.assign({}, initObj));
                case data_type_1.default.String:
                    const stringPropResource = resource;
                    const dataSourceName = stringPropResource.dataSource &&
                        (yield this._client.linkHelper.nameFromDataSourceAsync(stringPropResource.dataSource));
                    return new base_1.StringPropertyDefinition(resource.name, Object.assign(Object.assign({}, initObj), { contentType: stringPropResource.contentType, validationExpression: stringPropResource.validationExpression, dataSourceName: dataSourceName }));
                default:
                    throw (0, string_format_1.default)(error_messages_1.default.UnsupportedMemberDefinition, resource.name, data_type_1.default[resource.type]);
            }
        });
    }
    mapRelationDefinitionAsync(resource) {
        return __awaiter(this, void 0, void 0, function* () {
            guard_1.default.notNullOrUndefined(resource);
            guard_1.default.notNullOrUndefined(resource.role, "role");
            guard_1.default.notNullOrUndefined(resource.cardinality, "cardinality");
            const associatedEntityDefinitionName = yield this._client.linkHelper.nameFromDefinitionAsync(resource.associatedEntityDefinition);
            const relationDefinition = new base_1.RelationDefinition(resource.name, {
                allowNavigation: resource.allowNavigation,
                associatedEntityDefinitionName: associatedEntityDefinitionName != null ? associatedEntityDefinitionName : undefined,
                pathHierarchyScore: resource.pathHierarchyScore,
                childIsMandatory: resource.childIsMandatory != null ? resource.childIsMandatory : false,
                parentIsMandatory: resource.parentIsMandatory != null ? resource.parentIsMandatory : false,
                completionIsCopied: resource.completionIsCopied,
                contentIsCopied: resource.contentIsCopied,
                inheritsSecurity: resource.inheritsSecurity,
                isNested: resource.isNested,
                isPathHierarchyRelation: resource.isPathHierarchyRelation,
                isPathRelation: resource.isPathRelation,
                isRenditionRelation: resource.isRenditionRelation,
                isTaxonomyHierarchyRelation: resource.isTaxonomyHierarchyRelation,
                isTaxonomyRelation: resource.isTaxonomyRelation,
                associatedLabels: JSON.parse(JSON.stringify(resource.associatedLabels)),
                nestedPermissions: resource.nestedPermissions,
                cardinality: relation_cardinality_mapper_1.RelationCardinalityMapper.mapToEnumValue(resource.cardinality),
                role: relation_role_mapper_1.RelationRoleMapper.mapToEnumValue(resource.role),
                childConditionalValidation: resource.childConditionalValidation,
                parentConditionalValidation: resource.parentConditionalValidation,
            });
            if (resource.nestedProperties != null) {
                relationDefinition.nestedProperties.push(...resource.nestedProperties);
            }
            return relationDefinition;
        });
    }
    //#endregion
    //#region To API resource
    mapMemberDefinitionResourcesAsync(memberDefinitions) {
        return __awaiter(this, void 0, void 0, function* () {
            if (memberDefinitions == null || memberDefinitions.length === 0)
                return [];
            const list = [];
            for (const memberDefinition of memberDefinitions) {
                const resource = yield this.mapMemberDefinitionResourceAsync(memberDefinition);
                if (resource) {
                    list.push(resource);
                }
            }
            return list;
        });
    }
    mapMemberDefinitionResourceAsync(memberDefinition) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!memberDefinition)
                return null;
            let resource;
            if (memberDefinition instanceof base_1.PropertyDefinition) {
                resource = yield this.mapPropertyDefinitionResourceAsync(memberDefinition);
            }
            else if (memberDefinition instanceof base_1.RelationDefinition) {
                resource = yield this.mapRelationDefinitionResourceAsync(memberDefinition);
            }
            else {
                throw (0, string_format_1.default)(error_messages_1.default.UnsupportedMemberDefinition, memberDefinition.name, data_type_1.default[memberDefinition.type]);
            }
            if (!resource)
                return null;
            resource.helpText = JSON.parse(JSON.stringify(memberDefinition.helpText));
            resource.labels = JSON.parse(JSON.stringify(memberDefinition.labels));
            resource.conditions = yield this._memberConditionMapper.mapMemberConditionResourcesAsync(memberDefinition.conditions);
            resource.isConditional = memberDefinition.isConditional;
            resource.isSecured = memberDefinition.isSecured;
            resource.isSystemOwned = memberDefinition.isSystemOwned;
            resource.name = memberDefinition.name;
            resource.allowUpdates = memberDefinition.allowUpdates;
            resource.canTriggerConditionalMembers = memberDefinition.canTriggerConditionalMembers;
            resource.canWrite = memberDefinition.canWrite;
            return resource;
        });
    }
    mapPropertyDefinitionResourceAsync(definition) {
        return __awaiter(this, void 0, void 0, function* () {
            var _a, _b, _c, _d;
            if (!definition)
                return null;
            let resource;
            const initObj = {
                type: definition.type,
                name: definition.name,
                boost: definition.boost != null ? definition.boost : false,
                includeInCompletion: definition.includeInCompletion,
                includeInContent: definition.includeInContent,
                indexed: definition.indexed,
                isMandatory: definition.isMandatory,
                isUnique: definition.isUnique,
                isMultiLanguage: definition.isMultiLanguage,
                isMultiValue: definition.isMultiValue,
                canTriggerConditionalMembers: (_a = definition.canTriggerConditionalMembers) !== null && _a !== void 0 ? _a : false,
                canWrite: (_b = definition.canWrite) !== null && _b !== void 0 ? _b : false,
                ignoreOnExport: (_c = definition.ignoreOnExport) !== null && _c !== void 0 ? _c : false,
                storedInGraph: (_d = definition.storedInGraph) !== null && _d !== void 0 ? _d : false,
            };
            switch (definition.type) {
                case data_type_1.default.Boolean:
                    resource = new property_definition_resource_1.BooleanPropertyDefinitionResource(Object.assign({}, initObj));
                    break;
                case data_type_1.default.DateTime:
                    resource = new property_definition_resource_1.DateTimePropertyDefinitionResource(Object.assign({}, initObj));
                    break;
                case data_type_1.default.DateTimeOffset:
                    resource = new property_definition_resource_1.DateTimeOffsetPropertyDefinitionResource(Object.assign({}, initObj));
                    break;
                case data_type_1.default.Decimal:
                    resource = new property_definition_resource_1.DecimalPropertyDefinitionResource(Object.assign({}, initObj));
                    break;
                case data_type_1.default.Integer:
                    resource = new property_definition_resource_1.IntegerPropertyDefinitionResource(Object.assign({}, initObj));
                    break;
                case data_type_1.default.Json:
                    const jsonPropDefinition = definition;
                    resource = new property_definition_resource_1.JsonPropertyDefinitionResource(Object.assign(Object.assign({}, initObj), { contentType: jsonPropDefinition.contentType }));
                    break;
                case data_type_1.default.Long:
                    resource = new property_definition_resource_1.LongPropertyDefinitionResource(Object.assign({}, initObj));
                    break;
                case data_type_1.default.String:
                    const stringPropDefinition = definition;
                    const dataSourceLink = stringPropDefinition.dataSourceName &&
                        (yield this._client.linkHelper.dataSourceToLinkAsync(stringPropDefinition.dataSourceName));
                    resource = new property_definition_resource_1.StringPropertyDefinitionResource(Object.assign(Object.assign({}, initObj), { contentType: stringPropDefinition.contentType, validationExpression: stringPropDefinition.validationExpression, dataSource: dataSourceLink || null }));
                    break;
                default:
                    throw (0, string_format_1.default)(error_messages_1.default.UnsupportedMemberDefinition, definition.name, data_type_1.default[definition.type]);
            }
            return resource;
        });
    }
    mapRelationDefinitionResourceAsync(definition) {
        return __awaiter(this, void 0, void 0, function* () {
            if (!definition)
                return null;
            const associatedEntityDefinitionLink = yield this._client.linkHelper.definitionToLinkAsync(definition.associatedEntityDefinitionName);
            return new relation_definition_resource_1.RelationDefinitionResource({
                associatedEntityDefinition: associatedEntityDefinitionLink,
                allowNavigation: definition.allowNavigation,
                associatedLabels: JSON.parse(JSON.stringify(definition.associatedLabels)),
                pathHierarchyScore: definition.pathHierarchyScore,
                childIsMandatory: definition.childIsMandatory,
                completionIsCopied: definition.completionIsCopied,
                contentIsCopied: definition.contentIsCopied,
                inheritsSecurity: definition.inheritsSecurity,
                isNested: definition.isNested,
                isPathHierarchyRelation: definition.isPathHierarchyRelation,
                isPathRelation: definition.isPathRelation,
                isRenditionRelation: definition.isRenditionRelation,
                isTaxonomyHierarchyRelation: definition.isTaxonomyHierarchyRelation,
                isTaxonomyRelation: definition.isTaxonomyRelation,
                nestedPermissions: definition.nestedPermissions,
                nestedProperties: JSON.parse(JSON.stringify(definition.nestedProperties)),
                parentIsMandatory: definition.parentIsMandatory,
                cardinality: relation_cardinality_mapper_1.RelationCardinalityMapper.mapToType(definition.cardinality),
                role: relation_role_mapper_1.RelationRoleMapper.mapToType(definition.role),
                childConditionalValidation: definition.childConditionalValidation,
                parentConditionalValidation: definition.parentConditionalValidation,
            });
        });
    }
}
exports.MemberDefinitionMapper = MemberDefinitionMapper;
//# sourceMappingURL=member-definition-mapper.js.map