"use strict";
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);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var RoleMetadataService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RoleMetadataService = void 0;
const common_1 = require("@nestjs/common");
const core_1 = require("@nestjs/core");
const typeorm_1 = require("@nestjs/typeorm");
const crud_service_1 = require("./crud.service");
const typeorm_2 = require("typeorm");
const error_messages_1 = require("../constants/error-messages");
const permission_metadata_repository_1 = require("../repository/permission-metadata.repository");
const role_metadata_repository_1 = require("../repository/role-metadata.repository");
let RoleMetadataService = RoleMetadataService_1 = class RoleMetadataService extends crud_service_1.CRUDService {
    constructor(entityManager, repo, permissionRepository, moduleRef) {
        super(entityManager, repo, 'roleMetadata', 'solid-core', moduleRef);
        this.entityManager = entityManager;
        this.repo = repo;
        this.permissionRepository = permissionRepository;
        this.moduleRef = moduleRef;
        this.logger = new common_1.Logger(RoleMetadataService_1.name);
    }
    async findRoleByName(roleName) {
        const entity = await this.repo.findOne({
            where: {
                name: roleName
            },
            relations: {
                permissions: true
            }
        });
        if (!entity) {
            throw new common_1.NotFoundException(`Entity #${roleName} not found`);
        }
        return entity;
    }
    async createRolesIfNotExists(roles) {
        for (let id = 0; id < roles.length; id++) {
            try {
                const roleObj = roles[id];
                const existingRole = await this.repo.findOne({
                    where: {
                        name: roleObj.name,
                    },
                    relations: {},
                });
                if (!existingRole) {
                    this.logger.debug(`Role ${roleObj.name} does not exist, hence creating`);
                    let permissions = [];
                    if (roleObj.permissions && roleObj.permissions.length > 0) {
                        await Promise.all(roleObj.permissions.map(permission => this.preloadPermissionByName(permission.name)));
                    }
                    const role = this.repo.create({ ...roleObj });
                    await this.repo.save(role);
                }
                else {
                }
            }
            catch (error) {
                this.logger.error(error);
            }
        }
    }
    async addAllPermissionsToRole(roleName) {
        return await this._addPermissionsToRole(roleName, null);
    }
    async addPermissionsToRole(roleName, permissionNames) {
        return await this._addPermissionsToRole(roleName, permissionNames);
    }
    async addPermissionToRole(roleName, permissionName) {
        return await this._addPermissionsToRole(roleName, permissionName);
    }
    async _addPermissionsToRole(roleName, permissionNames) {
        const role = await this.repo.findOne({
            where: { name: roleName },
            relations: {
                permissions: true
            }
        });
        if (!role) {
            throw new Error(`Role '${roleName}' not found.`);
        }
        let newPermissions;
        if (permissionNames && permissionNames.length != 0) {
            newPermissions = await this.permissionRepository.find({ where: { name: (0, typeorm_2.In)(permissionNames) } });
            if (newPermissions.length !== permissionNames.length) {
                throw new Error(`One or more permissions not found.`);
            }
        }
        else {
            newPermissions = await this.permissionRepository.find();
            if (newPermissions.length == 0) {
                throw new Error(`No permissions configured in the system. Did you forget to run the PermissionSeederService?`);
            }
        }
        if (role.permissions && role.permissions.length > 0) {
            for (let i = 0; i < newPermissions.length; i++) {
                const newPermission = newPermissions[i];
                let newPermissionFound = true;
                for (let j = 0; j < role.permissions.length; j++) {
                    const existingPermission = role.permissions[j];
                    if (existingPermission.name === newPermission.name) {
                        newPermissionFound = false;
                        break;
                    }
                }
                if (newPermissionFound) {
                    role.permissions.push(newPermission);
                }
            }
        }
        else {
            role.permissions = newPermissions;
        }
        return await this.repo.save(role);
    }
    async removePermissionsFromRole(roleName, permissionNames) {
        const role = await this.repo.findOne({
            where: {
                name: roleName
            },
            relations: {
                permissions: true
            }
        });
        if (!role) {
            throw new Error(error_messages_1.ERROR_MESSAGES.ROLE_NOT_FOUND(roleName));
        }
        role.permissions = role.permissions.filter(permission => !permissionNames.includes(permission.name));
        return await this.repo.save(role);
    }
    async preloadPermissionByName(name) {
        const existingPermission = await this.permissionRepository.findOne({
            where: { name },
        });
        if (!existingPermission) {
            throw new common_1.NotFoundException(error_messages_1.ERROR_MESSAGES.PERMISSION_NOT_EXIST(name));
        }
        return existingPermission;
    }
};
exports.RoleMetadataService = RoleMetadataService;
exports.RoleMetadataService = RoleMetadataService = RoleMetadataService_1 = __decorate([
    (0, common_1.Injectable)(),
    __param(0, (0, typeorm_1.InjectEntityManager)()),
    __metadata("design:paramtypes", [typeorm_2.EntityManager,
        role_metadata_repository_1.RoleMetadataRepository,
        permission_metadata_repository_1.PermissionMetadataRepository,
        core_1.ModuleRef])
], RoleMetadataService);
//# sourceMappingURL=role-metadata.service.js.map