"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 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) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
        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;
                if (undefined !== entity[defaultAttribute]) {
                    ref = entity[defaultAttribute];
                }
                else {
                    try {
                        ref = await this.insideRestService.read(uri, ctx);
                        if (entity_name_1.EntityName.objectTree === ((_a = ref.entityCtx) === null || _a === void 0 ? void 0 : _a.entityType) &&
                            lodash_1.isObject((_c = (_b = ctx.uriContext) === null || _b === void 0 ? void 0 : _b.returnedEntity) === null || _c === void 0 ? void 0 : _c.value) &&
                            !lodash_1.isArray((_e = (_d = ctx.uriContext) === null || _d === void 0 ? void 0 : _d.returnedEntity) === null || _e === void 0 ? void 0 : _e.value) &&
                            entity_name_1.EntityName.objectTree === ((_j = (_h = (_g = (_f = ctx.uriContext) === null || _f === void 0 ? void 0 : _f.returnedEntity) === null || _g === void 0 ? void 0 : _g.value) === null || _h === void 0 ? void 0 : _h.entityCtx) === null || _j === void 0 ? void 0 : _j.entityType) &&
                            !ref.aliasUri &&
                            ref.treeNode &&
                            ref.treeNode.parentTreeId ===
                                ctx.uriContext.returnedEntity.value.treeNode.id) {
                            insertRef = false;
                        }
                        else if (entity_name_1.EntityName.objectTree === ((_k = ref.entityCtx) === null || _k === void 0 ? void 0 : _k.entityType) &&
                            lodash_1.isObject((_m = (_l = ctx.uriContext) === null || _l === void 0 ? void 0 : _l.returnedEntity) === null || _m === void 0 ? void 0 : _m.value) &&
                            !lodash_1.isArray((_p = (_o = ctx.uriContext) === null || _o === void 0 ? void 0 : _o.returnedEntity) === null || _p === void 0 ? void 0 : _p.value) &&
                            entity_name_1.EntityName.objectNode === ((_t = (_s = (_r = (_q = ctx.uriContext) === null || _q === void 0 ? void 0 : _q.returnedEntity) === null || _r === void 0 ? void 0 : _r.value) === null || _s === void 0 ? void 0 : _s.entityCtx) === null || _t === void 0 ? void 0 : _t.entityType) &&
                            !ref.aliasUri && // parent of a new tree, not loaded
                            ref.treeNode &&
                            ref.treeNode.parentTreeId ===
                                ctx.uriContext.returnedEntity.value.parentTreeId) {
                            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) {
                            entity[newAttribute] = ref;
                        }
                    }
                }
            }
            if (!this.isExcludedKey(key, ctx)) {
                if (lodash_1.isArray(entity[key])) {
                    for (const subEntity of entity[key]) {
                        await this.completeReturnedEntity(subEntity, ctx);
                    }
                }
                else if (lodash_1.isObject(entity[key])) {
                    await this.completeReturnedEntity(entity[key], ctx);
                }
            }
        }
    }
};
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