//
// Copyright (c) alveus.dev. All rights reserved. Licensed under the MIT License.
//
using Astral.Core.Entities;
using Astral.Core.Exceptions;
using Astral.Core.RepositoryInterfaces;
using Astral.Services.Dtos;
using Astral.Services.Exceptions;
using Astral.Services.Interfaces;
using AutoMapper;
using Injectio.Attributes;
using Microsoft.Extensions.Logging;
namespace Astral.Services.Services;
///
[RegisterScoped]
public class UserGroupService : IUserGroupService
{
private readonly ILogger _logger;
private readonly IMapper _mapper;
private readonly IUserGroupRepository _userGroupRepository;
private readonly IUserRepository _userRepository;
///
/// Initializes a new instance of the class.
///
/// Instance of .
/// Instance of .
/// Instance of .
/// Instance of .
public UserGroupService(
IUserGroupRepository userGroupRepository,
IUserRepository userRepository,
IMapper mapper,
ILogger logger)
{
_userGroupRepository = userGroupRepository;
_userRepository = userRepository;
_mapper = mapper;
_logger = logger;
}
///
public async Task CreateUserGroup(Guid ownerUserId, string title, string description)
{
var user = await _userRepository.FindByIdAsync(ownerUserId);
if (user is null)
{
_logger.LogError("Attempted to create a user group for a user that does not exist: {userId}", ownerUserId);
throw new UserNotFoundException();
}
var uniqueId = await GetUniqueId();
var userGroup = new UserGroup
{
Id = uniqueId,
CreatedAt = DateTime.UtcNow,
OwnerUserId = ownerUserId,
Title = title,
Description = description ?? string.Empty,
Internal = false
};
_logger.LogInformation(
"Creating new user group {groupTitle} [{groupId}] for user {user} [{userId}]",
userGroup.Title,
userGroup.Id,
user.Username,
user.Id);
await _userGroupRepository.AddAsync(userGroup);
return _mapper.Map(userGroup);
}
///
public async Task CreateInternalGroup(Guid ownerUserId, string title, string description)
{
var user = await _userRepository.FindByIdAsync(ownerUserId);
if (user is null)
{
_logger.LogError("Attempted to create a user group for a user that does not exist: {userId}", ownerUserId);
throw new UserNotFoundException();
}
var uniqueId = await GetUniqueId();
var userGroup = new UserGroup
{
Id = uniqueId,
CreatedAt = DateTime.UtcNow,
OwnerUserId = ownerUserId,
Title = title,
Description = description ?? string.Empty,
Internal = true
};
_logger.LogInformation(
"Creating new internal user group {groupTitle} [{groupId}] for user {user} [{userId}]",
userGroup.Title,
userGroup.Id,
user.Username,
user.Id);
await _userGroupRepository.AddAsync(userGroup);
return _mapper.Map(userGroup);
}
///
/// Create a unique guid.
///
/// The new guid.
private async Task GetUniqueId()
{
var attempt = 0;
const int maxAttempts = 10;
var newId = Guid.NewGuid();
while (await _userGroupRepository.FindByIdAsync(newId) is not null)
{
attempt++;
if (attempt >= maxAttempts)
{
_logger.LogCritical("Unable to generate a unique guid for user group");
throw new UnexpectedErrorException();
}
newId = Guid.NewGuid();
}
return newId;
}
}