"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransientUriReferenceService = void 0;
const tslib_1 = require("tslib");
const core_1 = require("@loopback/core");
const lodash_1 = require("lodash");
const helper_1 = require("../../helper");
const entity_name_1 = require("../../models/entity-name");
const transient_entity_service_1 = require("../transient-entity/transient-entity.service");
const inside_rest_service_1 = require("./inside-rest.service");
const transient_uri_reference_const_1 = require("./transient-uri-reference.const");
let TransientUriReferenceService = class TransientUriReferenceService {
    constructor(transientEntityService, insideRestService) {
        this.transientEntityService = transientEntityService;
        this.insideRestService = insideRestService;
        this.providerId = transient_uri_reference_const_1.TRANSIENT_URI_PROVIDER;
        this.serviceId = TransientUriReferenceService.name;
        this.description = 'Add references to ObjectTree, ObjectNode and ObjectType entities when they are referenced by an Uri field ended respectivly by ObjectTreeUri, ObjectNodeUri or ObjectTypeUri';
        this.transientEntityService.registerTransientEntityService(entity_name_1.EntityName.objectNode, this);
    }
    isUriObjectReference(key, ctx) {
        return (key.endsWith('ObjectTreeUri') ||
            key.endsWith('ObjectNodeUri') ||
            key.endsWith('ObjectTypeUri'));
    }
    getObjectReferenceAttributeName(key, ctx) {
        return key
            .replace('ObjectTreeUri', 'Tree')
            .replace('ObjectNodeUri', 'Node')
            .replace('ObjectTypeUri', 'Type');
    }
    isExcludedKey(key, ctx) {
        return -1 < lodash_1.indexOf(['aclList', 'entityCtx'], key);
    }
    async completeReturnedEntity(entity, ctx, addedReferences = []) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
        helper_1.cancelRecursive(entity);
        for (const key in entity) {
            if (key.endsWith('Uri') &&
                entity[key] &&
                lodash_1.isString(entity[key]) &&
                this.isUriObjectReference(key, ctx)) {
                const uri = entity[key];
                const defaultAttribute = key.substr(0, key.length - 3);
                const newAttribute = this.getObjectReferenceAttributeName(key, ctx);
                let ref = undefined;
                let insertRef = false;
                const addedRefernceId = ((_a = entity.entityCtx) === null || _a === void 0 ? void 0 : _a.entityType) + ':' + entity.id + '.' + newAttribute;
                if (undefined !== entity[defaultAttribute]) {
                    ref = entity[defaultAttribute];
                    addedReferences.push(addedRefernceId);
                }
                else {
                    try {
                        ref = await this.insideRestService.read(uri, ctx);
                        if (entity_name_1.EntityName.objectTree === ((_b = ref.entityCtx) === null || _b === void 0 ? void 0 : _b.entityType) &&
                            lodash_1.isObject((_d = (_c = ctx.uriContext) === null || _c === void 0 ? void 0 : _c.returnedEntity) === null || _d === void 0 ? void 0 : _d.value) &&
                            !lodash_1.isArray((_f = (_e = ctx.uriContext) === null || _e === void 0 ? void 0 : _e.returnedEntity) === null || _f === void 0 ? void 0 : _f.value) &&
                            entity_name_1.EntityName.objectTree === ((_k = (_j = (_h = (_g = ctx.uriContext) === null || _g === void 0 ? void 0 : _g.returnedEntity) === null || _h === void 0 ? void 0 : _h.value) === null || _j === void 0 ? void 0 : _j.entityCtx) === null || _k === void 0 ? void 0 : _k.entityType) &&
                            !ref.aliasUri &&
                            ref.treeNode &&
                            ref.treeNode.parentTreeId ===
                                ctx.uriContext.returnedEntity.value.treeNode.id) {
                            insertRef = false;
                        }
                        else if (entity_name_1.EntityName.objectTree === ((_l = ref.entityCtx) === null || _l === void 0 ? void 0 : _l.entityType) &&
                            lodash_1.isObject((_o = (_m = ctx.uriContext) === null || _m === void 0 ? void 0 : _m.returnedEntity) === null || _o === void 0 ? void 0 : _o.value) &&
                            !lodash_1.isArray((_q = (_p = ctx.uriContext) === null || _p === void 0 ? void 0 : _p.returnedEntity) === null || _q === void 0 ? void 0 : _q.value) &&
                            entity_name_1.EntityName.objectNode === ((_u = (_t = (_s = (_r = ctx.uriContext) === null || _r === void 0 ? void 0 : _r.returnedEntity) === null || _s === void 0 ? void 0 : _s.value) === null || _t === void 0 ? void 0 : _t.entityCtx) === null || _u === void 0 ? void 0 : _u.entityType) &&
                            !ref.aliasUri && // parent of a new tree, not loaded
                            ref.treeNode &&
                            ref.treeNode.parentTreeId ===
                                ctx.uriContext.returnedEntity.value.parentTreeId) {
                            insertRef = false;
                        }
                        else if (lodash_1.isObject((_w = (_v = ctx.uriContext) === null || _v === void 0 ? void 0 : _v.returnedEntity) === null || _w === void 0 ? void 0 : _w.value) &&
                            !lodash_1.isArray((_y = (_x = ctx.uriContext) === null || _x === void 0 ? void 0 : _x.returnedEntity) === null || _y === void 0 ? void 0 : _y.value) &&
                            entity_name_1.EntityName.objectTree === ((_2 = (_1 = (_0 = (_z = ctx.uriContext) === null || _z === void 0 ? void 0 : _z.returnedEntity) === null || _0 === void 0 ? void 0 : _0.value) === null || _1 === void 0 ? void 0 : _1.entityCtx) === null || _2 === void 0 ? void 0 : _2.entityType) &&
                            entity_name_1.EntityName.objectNode === ((_3 = entity.entityCtx) === null || _3 === void 0 ? void 0 : _3.entityType)
                        // don't load ref in node while laoding tree
                        ) {
                            insertRef = false;
                        }
                        else {
                            insertRef = true;
                        }
                        // eslint-disable-next-line no-empty
                    }
                    catch (error) { }
                    if ((ref === null || ref === void 0 ? void 0 : ref.id) && ref.uri) {
                        entity[newAttribute + 'Id'] = ref.id;
                        entity[newAttribute + 'Uri'] = ref.uri;
                        if (insertRef && !addedReferences.includes(addedRefernceId)) {
                            entity[newAttribute] = ref;
                            addedReferences.push(addedRefernceId);
                        }
                    }
                }
            }
            if (!this.isExcludedKey(key, ctx)) {
                if (lodash_1.isArray(entity[key])) {
                    for (const subEntity of entity[key]) {
                        await this.completeReturnedEntity(subEntity, ctx, addedReferences);
                    }
                }
                else if (lodash_1.isObject(entity[key])) {
                    await this.completeReturnedEntity(entity[key], ctx, addedReferences);
                }
            }
        }
    }
};
TransientUriReferenceService = tslib_1.__decorate([
    tslib_1.__param(0, core_1.service(transient_entity_service_1.TransientEntityService)),
    tslib_1.__param(1, core_1.service(inside_rest_service_1.InsideRestService)),
    tslib_1.__metadata("design:paramtypes", [transient_entity_service_1.TransientEntityService,
        inside_rest_service_1.InsideRestService])
], TransientUriReferenceService);
exports.TransientUriReferenceService = TransientUriReferenceService;
//# sourceMappingURL=transient-uri-reference.service.js.map