"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractEntityInterceptor = void 0;
const lodash_1 = require("lodash");
const application_service_1 = require("./../services/application.service");
const abstract_interceptor_1 = require("./abstract.interceptor");
class AbstractEntityInterceptor extends abstract_interceptor_1.AbstractInterceptor {
    constructor(abstractEntityService, ctx, applicationService) {
        super();
        this.abstractEntityService = abstractEntityService;
        this.ctx = ctx;
        this.applicationService = applicationService;
    }
    value() {
        return this.intercept.bind(this);
    }
    async intercept(invocationCtx, next) {
        var _a, _b;
        await this.getUriParts(invocationCtx, this.ctx);
        let entityName = undefined;
        let entityActionType = undefined;
        let entityId = undefined;
        let entity = undefined;
        if (invocationCtx.targetName &&
            invocationCtx.targetName in this.applicationService.entityActions) {
            entityName = this.applicationService.entityActions[invocationCtx.targetName].entityName;
            entityActionType = this.applicationService.entityActions[invocationCtx.targetName].entityActionType;
            switch (entityActionType) {
                case application_service_1.EntityActionType.create:
                    entity = invocationCtx.args[0];
                    break;
                case application_service_1.EntityActionType.update:
                    entityId = invocationCtx.args[0];
                    entity = invocationCtx.args[1];
                    break;
                case application_service_1.EntityActionType.delete:
                    entityId = invocationCtx.args[0];
                    break;
                case application_service_1.EntityActionType.read:
                    entityId = invocationCtx.args[0];
                    break;
            }
        }
        // eslint-disable-next-line no-useless-catch
        try {
            //      invocationCtx.targetName = 'ObjectTypeController.prototype.find'
            let result = undefined;
            // Add pre-invocation logic here
            if (this.abstractEntityService.interceptRequest &&
                entityName &&
                entityActionType) {
                const interceptionResult = await this.abstractEntityService.interceptRequest(entityName, entityActionType, entityId, entity, this.ctx);
                if (false === interceptionResult) {
                    return;
                }
                if (true !== interceptionResult) {
                    result = interceptionResult;
                }
            }
            if (undefined === result &&
                this.abstractEntityService.interceptAllRequest) {
                await this.abstractEntityService.interceptAllRequest(this.ctx);
            }
            // invocation
            if (undefined === result) {
                result = await next();
            }
            // Add post-invocation logic here
            if (Array.isArray(result)) {
                if (result.length > 0) {
                    let completeDone = false;
                    if (((_a = result[0]) === null || _a === void 0 ? void 0 : _a.uri) &&
                        this.abstractEntityService.completeReturnedEntities) {
                        const uriParts = await this.getUriParts(invocationCtx, this.ctx);
                        const returnedEntityName = this.getEntityName((_b = result[0]) === null || _b === void 0 ? void 0 : _b.uri, uriParts.baseUri);
                        if (lodash_1.every(result, (oneResult) => {
                            return (this.getEntityName(oneResult.uri, uriParts.baseUri) ===
                                returnedEntityName);
                        })) {
                            await this.abstractEntityService.completeReturnedEntities(returnedEntityName, result, this.ctx);
                            completeDone = true;
                        }
                    }
                    if (this.abstractEntityService.completeReturnedEntity &&
                        !completeDone) {
                        for (const oneResult of result) {
                            const oneEntity = oneResult;
                            if (oneEntity === null || oneEntity === void 0 ? void 0 : oneEntity.uri) {
                                const uriParts = await this.getUriParts(invocationCtx, this.ctx);
                                const oneEntityName = this.getEntityName(oneEntity.uri, uriParts.baseUri);
                                await this.abstractEntityService.completeReturnedEntity(oneEntityName, oneResult, this.ctx);
                            }
                        }
                    }
                }
            }
            else if (lodash_1.isObject(result)) {
                const returnedEntity = result;
                if (this.abstractEntityService.completeReturnedEntity && (returnedEntity === null || returnedEntity === void 0 ? void 0 : returnedEntity.uri)) {
                    const uriParts = await this.getUriParts(invocationCtx, this.ctx);
                    const returnedEntityName = this.getEntityName(returnedEntity.uri, uriParts.baseUri);
                    await this.abstractEntityService.completeReturnedEntity(returnedEntityName, result, this.ctx);
                }
            }
            return result;
        }
        finally {
            if (this.abstractEntityService.makeFinallyTreatment &&
                entityName &&
                entityActionType) {
                await this.abstractEntityService.makeFinallyTreatment(entityName, entityActionType, entityId, entity, this.ctx);
            }
            if (this.abstractEntityService.makeAllFinallyTreatment) {
                await this.abstractEntityService.makeAllFinallyTreatment(this.ctx);
            }
        }
    }
}
exports.AbstractEntityInterceptor = AbstractEntityInterceptor;
//# sourceMappingURL=abstract-entity.interceptor.js.map