"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ApplicationService = exports.ObjectTreeProviderContext = exports.AccessRightsProviderContext = exports.ApplicationExtensionContext = exports.ObjectTypeName = exports.ExpectedValue = exports.CURRENT_CONTEXT = exports.CurrentContext = exports.WebSiteContext = exports.UriContext = exports.TypeContext = exports.AccessRightsContext = exports.TreeContext = exports.NodeContext = exports.MethodContext = exports.EntityActions = exports.EntityActionType = void 0;
const tslib_1 = require("tslib");
const _ = tslib_1.__importStar(require("lodash"));
const application_error_1 = require("./../helper/application-error");
var EntityActionType;
(function (EntityActionType) {
    EntityActionType["create"] = "create";
    EntityActionType["read"] = "read";
    EntityActionType["update"] = "update";
    EntityActionType["delete"] = "delete";
})(EntityActionType = exports.EntityActionType || (exports.EntityActionType = {}));
class EntityActions {
}
exports.EntityActions = EntityActions;
class MethodContext {
    constructor() {
        this.entity = new ExpectedValue();
    }
}
exports.MethodContext = MethodContext;
class NodeContext {
    constructor() {
        this.node = new ExpectedValue();
        this.tree = new ExpectedValue();
        this.owner = new ExpectedValue();
        this.namespace = new ExpectedValue();
        this.parent = new ExpectedValue();
        this.parentType = new ExpectedValue();
        this.objectSubType = new ExpectedValue();
        this.objectType = new ExpectedValue();
        this.brothers = new ExpectedValue();
        this.references = {};
    }
}
exports.NodeContext = NodeContext;
class TreeContext {
    constructor() {
        this.treeNode = new ExpectedValue();
        this.treeType = new ExpectedValue();
        this.treeChildren = new ExpectedValue();
    }
}
exports.TreeContext = TreeContext;
class AccessRightsContext {
    constructor() {
        this.copyToChildContext = true;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        this.rights = new ExpectedValue();
        this.user = new ExpectedValue();
        this.treeRootNodeId = new ExpectedValue();
        this.aclTrees = new ExpectedValue();
        this.rootRights = new ExpectedValue();
        this.authorization = new ExpectedValue();
    }
}
exports.AccessRightsContext = AccessRightsContext;
class TypeContext {
    constructor() {
        this.copyToChildContext = true;
        this.types = new ExpectedValue();
    }
}
exports.TypeContext = TypeContext;
class UriContext {
    constructor() {
        this.copyToChildContext = true;
        this.mainContext = false;
        this.uri = new ExpectedValue();
        this.returnedEntity = new ExpectedValue();
    }
}
exports.UriContext = UriContext;
class WebSiteContext {
    constructor() {
        this.copyToChildContext = true;
        this.urlNode = new ExpectedValue();
        this.webSiteTree = new ExpectedValue();
        this.webSitePageNode = new ExpectedValue();
        this.pageBaseUri = new ExpectedValue();
        this.siteBaseUriTree = new ExpectedValue();
        this.cachedContent = new ExpectedValue();
    }
}
exports.WebSiteContext = WebSiteContext;
class CurrentContext {
    constructor() {
        this.nodeContext = new NodeContext();
        this.treeContext = new TreeContext();
        this.accessRightsContext = new AccessRightsContext();
        this.typeContext = new TypeContext();
        this.uriContext = new UriContext();
        this.methodContext = new MethodContext();
        this.webSiteContext = new WebSiteContext();
    }
    static get(parentCtx, value = {}) {
        const ctx = new CurrentContext();
        for (const context in parentCtx) {
            if (parentCtx[context].copyToChildContext) {
                ctx[context] = parentCtx[context];
            }
        }
        ctx.uriContext.mainContext = false;
        if (value) {
            for (const key in value) {
                if (key in ctx) {
                    Object.assign(ctx[key], value[key]);
                }
                else {
                    ctx[key] = value[key];
                }
            }
        }
        return ctx;
    }
}
exports.CurrentContext = CurrentContext;
exports.CURRENT_CONTEXT = 'CURRENT_CONTEXT';
class ExpectedValue {
    constructor(value) {
        this._value = undefined;
        this.waitForValue = new Promise((resolve, reject) => {
            this.resolveValue = resolve;
        });
        if (undefined !== value) {
            this.value = value;
        }
    }
    get value() {
        return this._value;
    }
    set value(value) {
        this._value = value;
        this.resolveValue(this.value);
    }
    async getOrSetValue(searchValue) {
        if (undefined === this.value) {
            this.value = await searchValue();
        }
        return this.value;
    }
}
exports.ExpectedValue = ExpectedValue;
var ObjectTypeName;
(function (ObjectTypeName) {
    ObjectTypeName["REPOSITORY"] = "Repository";
    ObjectTypeName["USER"] = "User";
    ObjectTypeName["ANONYMOUS_USER"] = "AnonymousUser";
    ObjectTypeName["ACCESS_RIGHT_DEFINITION"] = "AccessRightsDefinition";
    ObjectTypeName["ACCESS_RIGHT_GROUP"] = "AccessRightsGroup";
    ObjectTypeName["ACCESS_RIGHT_OWNERS"] = "AccessRightsOwners";
    ObjectTypeName["ACCESS_RIGHT_ACCESS_MANAGERS"] = "AccessRightsAccessManagers";
    ObjectTypeName["TENANT"] = "Tenant";
    ObjectTypeName["REPOSITORY_CATEGORY"] = "RepositoryCategory";
})(ObjectTypeName = exports.ObjectTypeName || (exports.ObjectTypeName = {}));
class ApplicationExtensionContext {
    constructor() {
        this.ready = new Promise((resolve, reject) => {
            this.resolve = resolve;
            this.reject = reject;
        });
        this.types = {};
        this.nodes = {};
    }
}
exports.ApplicationExtensionContext = ApplicationExtensionContext;
class AccessRightsProviderContext extends ApplicationExtensionContext {
    constructor() {
        super(...arguments);
        this.types = {
            user: new ExpectedValue(),
            anonymousUser: new ExpectedValue(),
            accessRightsDefinition: new ExpectedValue(),
            accessRightsGroup: new ExpectedValue(),
            accessRightsOwners: new ExpectedValue(),
            accessRightsAccessManagers: new ExpectedValue(),
        };
        this.nodes = { rootACL: new ExpectedValue() };
    }
}
exports.AccessRightsProviderContext = AccessRightsProviderContext;
class ObjectTreeProviderContext extends ApplicationExtensionContext {
    constructor() {
        super(...arguments);
        this.types = {
            repository: new ExpectedValue(),
            category: new ExpectedValue(),
            tenant: new ExpectedValue(),
            folder: new ExpectedValue(),
        };
        this.nodes = {
            root: new ExpectedValue(),
            public: new ExpectedValue(),
            publicTemplates: new ExpectedValue(),
            demonstrationAccount: new ExpectedValue(),
            demonstrationExamples: new ExpectedValue(),
            demonstrationSandbox: new ExpectedValue(),
        };
    }
}
exports.ObjectTreeProviderContext = ObjectTreeProviderContext;
class ApplicationService {
    constructor() {
        this.entityActions = {};
        this.extensions = {
            ObjectTreeProvider: new ObjectTreeProviderContext(),
            AccessRightsProvider: new AccessRightsProviderContext(),
        };
        this.ready = Promise.all([
            this.tenantType.waitForValue,
            this.repositoryType.waitForValue,
            this.rootNode.waitForValue,
            this.userType.waitForValue,
            this.anonymousUserType.waitForValue,
            this.accessRightsDefinitionType.waitForValue,
            this.accessRightsGroupType.waitForValue,
            this.accessRightsOwnersType.waitForValue,
            this.accessRightsAccessManagersType.waitForValue,
        ]);
        this.allTypes = new ExpectedValue();
        this.implementedTypes = new ExpectedValue();
        this.implementingTypes = new ExpectedValue();
        this.parentTypes = new ExpectedValue();
        this.parentImplementingTypes = new ExpectedValue();
        this.implementingCommonTypes = new ExpectedValue();
    }
    get repositoryType() {
        return this.extensions.ObjectTreeProvider.types.repository;
    }
    get categoryType() {
        return this.extensions.ObjectTreeProvider.types.category;
    }
    get tenantType() {
        return this.extensions.ObjectTreeProvider.types.tenant;
    }
    get folderType() {
        return this.extensions.ObjectTreeProvider.types.folder;
    }
    get rootNode() {
        return this.extensions.ObjectTreeProvider.nodes.root;
    }
    get publicNode() {
        return this.extensions.ObjectTreeProvider.nodes.public;
    }
    get demonstrationAccountNode() {
        return this.extensions.ObjectTreeProvider.nodes.demonstrationAccount;
    }
    get demonstrationExamplesNode() {
        return this.extensions.ObjectTreeProvider.nodes.demonstrationExamples;
    }
    get demonstrationSandboxNode() {
        return this.extensions.ObjectTreeProvider.nodes.demonstrationSandbox;
    }
    get publicTemplatesNode() {
        return this.extensions.ObjectTreeProvider.nodes.publicTemplates;
    }
    get userType() {
        return this.extensions.AccessRightsProvider.types.user;
    }
    get anonymousUserType() {
        return this.extensions.AccessRightsProvider.types.anonymousUser;
    }
    get accessRightsDefinitionType() {
        return this.extensions.AccessRightsProvider.types.accessRightsDefinition;
    }
    get accessRightsGroupType() {
        return this.extensions.AccessRightsProvider.types.accessRightsGroup;
    }
    get accessRightsOwnersType() {
        return this.extensions.AccessRightsProvider.types.accessRightsOwners;
    }
    get accessRightsAccessManagersType() {
        return this.extensions.AccessRightsProvider.types
            .accessRightsAccessManagers;
    }
    get config() {
        return this.app.config;
    }
    getExtensionContext(extensionNameOrClass) {
        const extensionName = _.isString(extensionNameOrClass)
            ? extensionNameOrClass
            : extensionNameOrClass.name;
        if (!extensionName.endsWith('Provider')) {
            throw application_error_1.ApplicationError.unauthorizedValue({
                extensionName: 'Extension name should end with Provider',
            });
        }
        if (!(extensionName in this.extensions)) {
            this.extensions[extensionName] = new ApplicationExtensionContext();
        }
        return this.extensions[extensionName];
    }
}
exports.ApplicationService = ApplicationService;
ApplicationService.OBJECT_TYPE_NAMES = ObjectTypeName;
ApplicationService.OBJECT_NODE_NAMES = {
    [ApplicationService.OBJECT_TYPE_NAMES.REPOSITORY]: 'root',
    [ApplicationService.OBJECT_TYPE_NAMES.USER]: 'Admin',
    [ApplicationService.OBJECT_TYPE_NAMES.ANONYMOUS_USER]: 'AnonymousUser',
    [ApplicationService.OBJECT_TYPE_NAMES.ACCESS_RIGHT_DEFINITION]: 'AccessRights',
    [ApplicationService.OBJECT_TYPE_NAMES.ACCESS_RIGHT_GROUP]: 'UsersGroup',
    [ApplicationService.OBJECT_TYPE_NAMES.ACCESS_RIGHT_OWNERS]: 'OwnersGroup',
    [ApplicationService.OBJECT_TYPE_NAMES.ACCESS_RIGHT_ACCESS_MANAGERS]: 'AccessManagersGroup',
    [ApplicationService.OBJECT_TYPE_NAMES.TENANT]: 'Tenant',
    [ApplicationService.OBJECT_TYPE_NAMES.REPOSITORY_CATEGORY]: 'Category',
};
ApplicationService.CONTENT_TYPE = {
    USER: 'ContentUser',
    JSON: '',
};
//# sourceMappingURL=application.service.js.map