using APP.Models;
using CORE.Services;
using CORE.Session.Services;
namespace APP.Services
{
/// <summary>
/// Concrete class for managing user session data.
/// Provides methods to add, remove, retrieve, and
/// clear user session data.
/// Implemented as a concrete class because the behaviors
/// of this class are standard and are not expected to change.
/// </summary>
public class UserSessionService
{
// Constant key value to store and retrieve user session
// data in the session.
// Default private if no accessibility modifier is specified.
const string KEY = "UserSession";
// Services to be injected for user session data management.
private readonly SessionService _sessionService;
private readonly IService<UserRequest, UserResponse> _userService;
public UserSessionService(SessionService sessionService,
IService<UserRequest, UserResponse> userService)
{
_sessionService = sessionService;
_userService = userService;
}
/// <summary>
/// Retrieves the list of user session data for the specified
/// authenticated user. Then calculates the minimum, maximum
/// and average scores of the users if there is at least one
/// user. Finally adds a calculation summary item to the list
/// before returning it.
/// </summary>
/// <returns>List of user session response items including
/// a summary item. If no users data is found in the session,
/// returns an empty list.</returns>
public List<UserSessionResponse> Get()
{
var sessionUsers = _sessionService
.Get<List<UserSessionResponse>>(KEY);
if (sessionUsers is not null)
{
sessionUsers = sessionUsers.Where(
su => su.AuthenticatedUserId
== _sessionService.AuthenticatedUserId)
.ToList();
if (sessionUsers.Count > 0)
{
var minimumScoreText = sessionUsers
.Min(su => su.Score).ToString("N1");
var maximumScoreText = sessionUsers
.Max(su => su.Score).ToString("N1");
var averageScoreText = sessionUsers
.Average(su => su.Score).ToString("N1");
sessionUsers.Add(new UserSessionResponse
{
ScoreText = $"<b>Minimum Score:</b> {minimumScoreText}, " +
$"<b>Maximum Score:</b> {maximumScoreText}, " +
$"<b>Average Score:</b> {averageScoreText}"
});
}
return sessionUsers;
}
return new List<UserSessionResponse>();
}
/// <summary>
/// Adds the user retrieved from the Users database table by
/// the specified user ID parameter value if found and haven't been
/// added to users session before. Then sets the updated user list
/// in the authenticated user's session.
/// </summary>
/// <param name="userId">User ID to get the user from the
/// Users database table.</param>
public void Add(int userId)
{
var user = _userService.Single(userId);
if (user is not null)
{
var sessionUsers = Get();
if (!sessionUsers.Any(su => su.UserId == user.Id
&& su.AuthenticatedUserId == _sessionService.AuthenticatedUserId))
{
sessionUsers.Add(new UserSessionResponse
{
AuthenticatedUserId = _sessionService.AuthenticatedUserId,
UserId = user.Id,
UserName = user.UserName,
Score = user.Score,
ScoreText = user.Score.ToString("N1")
});
_sessionService.Set(KEY, sessionUsers);
}
}
}
/// <summary>
/// Removes the user from the authenticated users's session
/// then updates the user list in the session.
/// </summary>
/// <param name="userId">User ID to remove from the session.</param>
public void Remove(int userId)
{
var sessionUsers = Get();
var sessionUser = sessionUsers
.FirstOrDefault(su => su.UserId == userId
&& su.AuthenticatedUserId == _sessionService.AuthenticatedUserId);
if (sessionUser is not null)
{
sessionUsers.Remove(sessionUser);
_sessionService.Set(KEY, sessionUsers);
}
}
/// <summary>
/// Removes all users from the authenticated user's session
/// then updates the user list in the session.
/// </summary>
public void Clear()
{
var sessionUsers = Get();
sessionUsers.RemoveAll(
su => su.AuthenticatedUserId == _sessionService.AuthenticatedUserId);
_sessionService.Set(KEY, sessionUsers);
}
}
}