var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import GlobalCache from "../Infrastructure/GlobalCache";
import QueryHelper from "../Types/Database/QueryHelper";
import BaseService from "./BaseService";
import TeamMemberService from "./TeamMemberService";
import TeamPermissionService from "./TeamPermissionService";
import LIMIT_MAX from "../../Types/Database/LimitMax";
import ObjectID from "../../Types/ObjectID";
import Permission from "../../Types/Permission";
import UserPermissionUtil from "../Utils/UserPermission/UserPermission";
import PermissionNamespace from "../Types/Permission/PermissionNamespace";
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
export class AccessTokenService extends BaseService {
    constructor() {
        super();
    }
    async refreshUserAllPermissions(userId) {
        await this.refreshUserGlobalAccessPermission(userId);
        // query for all projects user belongs to.
        let teamMembers = await TeamMemberService.findBy({
            query: {
                userId: userId,
                hasAcceptedInvitation: true,
            },
            select: {
                projectId: true,
            },
            limit: LIMIT_MAX,
            skip: 0,
            props: {
                isRoot: true,
            },
        });
        if (!teamMembers) {
            teamMembers = [];
        }
        if (teamMembers.length === 0) {
            return;
        }
        const projectIds = teamMembers.map((teamMember) => {
            return teamMember.projectId;
        });
        for (const projectId of projectIds) {
            await this.refreshUserTenantAccessPermission(userId, projectId);
        }
    }
    async refreshUserGlobalAccessPermission(userId) {
        // query for all projects user belongs to.
        let teamMembers = await TeamMemberService.findBy({
            query: {
                userId: userId,
                hasAcceptedInvitation: true,
            },
            select: {
                projectId: true,
            },
            limit: LIMIT_MAX,
            skip: 0,
            props: {
                isRoot: true,
            },
        });
        if (!teamMembers) {
            teamMembers = [];
        }
        const projectIds = teamMembers.map((teamMember) => {
            return teamMember.projectId;
        });
        const permissionToStore = {
            projectIds,
            globalPermissions: [
                Permission.Public,
                Permission.User,
                Permission.CurrentUser,
            ],
            _type: "UserGlobalAccessPermission",
        };
        await GlobalCache.setJSON("user", userId.toString(), permissionToStore);
        return permissionToStore;
    }
    async getUserGlobalAccessPermission(userId) {
        const json = await UserPermissionUtil.getUserGlobalAccessPermissionFromCache(userId);
        if (!json) {
            return await this.refreshUserGlobalAccessPermission(userId);
        }
        return json;
    }
    async refreshUserTenantAccessPermission(userId, projectId) {
        // query for all projects user belongs to.
        const teamMembers = await TeamMemberService.findBy({
            query: {
                userId: userId,
                projectId: projectId,
                hasAcceptedInvitation: true,
            },
            select: {
                teamId: true,
            },
            limit: LIMIT_MAX,
            skip: 0,
            props: {
                isRoot: true,
            },
        });
        const teamIds = teamMembers.map((teamMember) => {
            return teamMember.teamId;
        });
        if (teamIds.length === 0) {
            return null;
        }
        // get team permissions.
        const teamPermissions = await TeamPermissionService.findBy({
            query: {
                teamId: QueryHelper.any(teamIds),
            },
            select: {
                permission: true,
                labels: {
                    _id: true,
                },
                isBlockPermission: true,
                scope: true,
            },
            limit: LIMIT_MAX,
            skip: 0,
            props: {
                isRoot: true,
            },
        });
        const userPermissions = [];
        for (const teamPermission of teamPermissions) {
            if (!teamPermission.labels) {
                teamPermission.labels = [];
            }
            userPermissions.push({
                permission: teamPermission.permission,
                labelIds: teamPermission.labels.map((label) => {
                    return label.id;
                }),
                isBlockPermission: teamPermission.isBlockPermission,
                scope: teamPermission.scope,
                _type: "UserPermission",
            });
        }
        const permission = UserPermissionUtil.getDefaultUserTenantAccessPermission(projectId);
        permission.permissions = permission.permissions.concat(userPermissions);
        await GlobalCache.setJSON(PermissionNamespace.ProjectPermission, UserPermissionUtil.buildTenantPermissionCacheKey(userId, projectId), permission);
        return permission;
    }
    async getDatabaseCommonInteractionPropsByUserAndProject(data) {
        const { userId, projectId } = data;
        return {
            userId: userId,
            userGlobalAccessPermission: (await this.getUserGlobalAccessPermission(userId)) || undefined,
            userTenantAccessPermission: {
                [projectId.toString()]: (await this.getUserTenantAccessPermission(userId, projectId)),
            },
            tenantId: projectId,
        };
    }
    async getUserTenantAccessPermission(userId, projectId) {
        const json = await UserPermissionUtil.getUserTenantAccessPermissionFromCache(userId, projectId);
        if (!json) {
            return await this.refreshUserTenantAccessPermission(userId, projectId);
        }
        return json;
    }
}
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [ObjectID]),
    __metadata("design:returntype", Promise)
], AccessTokenService.prototype, "refreshUserAllPermissions", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [ObjectID]),
    __metadata("design:returntype", Promise)
], AccessTokenService.prototype, "refreshUserGlobalAccessPermission", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [ObjectID]),
    __metadata("design:returntype", Promise)
], AccessTokenService.prototype, "getUserGlobalAccessPermission", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [ObjectID,
        ObjectID]),
    __metadata("design:returntype", Promise)
], AccessTokenService.prototype, "refreshUserTenantAccessPermission", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [Object]),
    __metadata("design:returntype", Promise)
], AccessTokenService.prototype, "getDatabaseCommonInteractionPropsByUserAndProject", null);
__decorate([
    CaptureSpan(),
    __metadata("design:type", Function),
    __metadata("design:paramtypes", [ObjectID,
        ObjectID]),
    __metadata("design:returntype", Promise)
], AccessTokenService.prototype, "getUserTenantAccessPermission", null);
export default new AccessTokenService();
//# sourceMappingURL=AccessTokenService.js.map