using GB5Shared.DTO.Framework.Login; using GB5Shared.GenerateAutoNumber; using GB5Shared.Resource.Response; using SwBLL.ClientDatabase; using SwBLL.DbServer; using SwDAL.CustomCode.UserResourceRole; using SwDAL.DTO.UserResourceRole; using SwDAL.Enums; using static GB5Shared.GB5Constant.Constant; namespace SwBLL.UserResourceRole; public class UserResourceRoleBLL : IUserResourceRoleBLL { private readonly IUserResourceRoleDAL _UserResourceRoleDAL; private readonly IDbServerBLL _DbServerBLL; private readonly IClientDatabaseBLL _ClientDatabaseBLL; private readonly AutoNumber _AutoNumber; public UserResourceRoleBLL( IUserResourceRoleDAL userResourceRoleDAL, IDbServerBLL dbServerBLL, IClientDatabaseBLL clientDatabaseBLL, AutoNumber autoNumber) { _UserResourceRoleDAL = userResourceRoleDAL; _DbServerBLL = dbServerBLL; _ClientDatabaseBLL = clientDatabaseBLL; _AutoNumber = autoNumber; } // ── Reads ───────────────────────────────────────────────────────────── public async Task> GetGrantsForUser(int userId, LoginDTO loginDTO, CancellationToken ct) { if (userId == 0) throw new ArgumentException("UserId is required.", nameof(userId)); return await _UserResourceRoleDAL.GetGrantsForUser(userId, loginDTO, ct).ConfigureAwait(false); } public async Task> GetGranteesForServer(int dbServerId, LoginDTO loginDTO, CancellationToken ct) { if (dbServerId == 0) throw new ArgumentException("DbServerId is required.", nameof(dbServerId)); return await _UserResourceRoleDAL.GetGranteesForServer(dbServerId, loginDTO, ct).ConfigureAwait(false); } public async Task> GetGranteesForClientDb(int clientDbId, LoginDTO loginDTO, CancellationToken ct) { if (clientDbId == 0) throw new ArgumentException("ClientDbId is required.", nameof(clientDbId)); return await _UserResourceRoleDAL.GetGranteesForClientDb(clientDbId, loginDTO, ct).ConfigureAwait(false); } public async Task GetEffectiveRole( int userId, int? dbServerId, int? clientDbId, LoginDTO loginDTO, CancellationToken ct) { if (userId == 0) throw new ArgumentException("UserId is required.", nameof(userId)); if (dbServerId is null && clientDbId is null) throw new ArgumentException("Either DbServerId or ClientDbId is required."); var role = await _UserResourceRoleDAL.GetEffectiveRole(userId, dbServerId, clientDbId, loginDTO, ct) .ConfigureAwait(false); return role is byte b ? (ClientDbLoginRole)b : null; } // ── Assign / Revoke ────────────────────────────────────────────────── public async Task AssignUserResourceRole(AssignUserResourceRoleDTO dto, LoginDTO loginDTO, CancellationToken ct) { if (dto == null) throw new ArgumentNullException(nameof(dto)); if (dto.UserId == 0) throw new ArgumentException("UserId is required.", nameof(dto)); if ((dto.DbServerId is null) == (dto.ClientDbId is null)) throw new ArgumentException("Exactly one of DbServerId/ClientDbId must be set.", nameof(dto)); if (!Enum.IsDefined(typeof(ClientDbLoginRole), dto.Role)) throw new ArgumentException($"Role {dto.Role} is not a defined ClientDbLoginRole.", nameof(dto)); if (dto.DbServerId is int dbServerId) { _ = await _DbServerBLL.GetById(dbServerId, loginDTO, ct).ConfigureAwait(false) ?? throw new InvalidOperationException($"DB server {dbServerId} not found."); } else { _ = await _ClientDatabaseBLL.GetById(dto.ClientDbId!.Value, loginDTO, ct).ConfigureAwait(false) ?? throw new InvalidOperationException($"Client database {dto.ClientDbId} not found."); } var auto = await _AutoNumber.GetNumberAsync(1, AUTONUMBERCONSTANT.SWCLIENTDATABASE, loginDTO); var now = DateTime.UtcNow; await _UserResourceRoleDAL.UpsertGrant(new UserResourceRoleDTO { UserResourceRoleId = auto.StartNumber, UserId = dto.UserId, DbServerId = dto.DbServerId, ClientDbId = dto.ClientDbId, Role = dto.Role, CreatedById = loginDTO.UserId, CreatedOn = now, ModifiedById = loginDTO.UserId, ModifiedOn = now, TenantId = loginDTO.ClientId, }, loginDTO, ct).ConfigureAwait(false); return SuccessResponse.SaveSuccess; } public async Task RevokeUserResourceRole(RevokeUserResourceRoleDTO dto, LoginDTO loginDTO, CancellationToken ct) { if (dto == null) throw new ArgumentNullException(nameof(dto)); if (dto.UserId == 0) throw new ArgumentException("UserId is required.", nameof(dto)); if ((dto.DbServerId is null) == (dto.ClientDbId is null)) throw new ArgumentException("Exactly one of DbServerId/ClientDbId must be set.", nameof(dto)); await _UserResourceRoleDAL.RevokeGrant(dto, loginDTO, ct).ConfigureAwait(false); return SuccessResponse.DeleteSuccessMessage; } }