using Microsoft.Extensions.Logging; using Model; using Model.Repository; using Shared; using EFMappers; using Entities; using Microsoft.EntityFrameworkCore; namespace Model2Entities; public partial class DbDataManager { public class UserRepository : IUserRepository { private readonly DbDataManager _dataManager; private readonly ILogger _logger; public UserRepository(DbDataManager dbDataManager, ILogger logger) { _dataManager = dbDataManager; _logger = logger; } public async Task> GetItems(int index, int count, string? orderingProperty = null, bool descending = false) => await GetUsers(index, count, this.ToEnum(orderingProperty), descending); public async Task> GetUsers(int index, int count, AthleteOrderCriteria? orderingProperty = null, bool descending = false) { _logger.LogInformation($"GetItems with index {index} and count {count}", index, count); _logger.LogInformation($"GetItems with orderingProperty {orderingProperty} and descending {descending}", orderingProperty, descending); var users = _dataManager.DbContext.AthletesSet.IncludeStandardProperties().GetItemsWithFilterAndOrdering(b => true, index, count, orderingProperty != AthleteOrderCriteria.None ? orderingProperty : null, descending).ToModels(); _logger.LogInformation($"Retrieved {users.Count()} users"); return await Task.FromResult(users); } public async Task GetItemById(int id) { _logger.LogInformation($"GetItemById with id {id}", id); var userEntity = await _dataManager.DbContext.AthletesSet.IncludeStandardProperties() .SingleOrDefaultAsync(a => a.IdAthlete == id); var user = userEntity != null ? userEntity.ToModel() : null; if (user != null) _logger.LogInformation($"Retrieved user with ID {id}"); else _logger.LogWarning($"No user found with ID {id}"); return await Task.FromResult(user); } public async Task UpdateItem(int oldItem, User newItem) { _logger.LogInformation($"UpdateItem with id {oldItem}", oldItem); var originalEntity = _dataManager.DbContext.AthletesSet.Find(oldItem); if (originalEntity == null) { _logger.LogWarning($"No user found with ID {oldItem}"); return await Task.FromResult(null); } var originalEntry = _dataManager.DbContext.Entry(originalEntity); var values = typeof(AthleteEntity).GetProperties().Where(ppty => ppty.Name != "IdAthlete") .ToDictionary(ppty => ppty.Name, ppty => ppty.GetValue(newItem.ToEntity())); originalEntry.CurrentValues.SetValues(values); _dataManager.DbContext.AthletesSet.Attach(originalEntity); _dataManager.DbContext.Entry(originalEntity).State = EntityState.Modified; _dataManager.DbContext.SaveChanges(); var updatedUser = originalEntity.ToModel(); if (updatedUser != null) _logger.LogInformation($"Updated user with ID {oldItem}"); else _logger.LogWarning($"No user found with ID {oldItem}"); return await Task.FromResult(updatedUser); } public async Task AddItem(User item) { _logger.LogInformation("Adding new user"); var addedUser = (await _dataManager.DbContext.AddItem(item.ToEntity()))?.ToModel(); if (addedUser != null) _logger.LogInformation($"Added user with ID {addedUser.Id}"); else _logger.LogError("Failed to add user"); return await Task.FromResult(addedUser); } public async Task DeleteItem(int item) { _logger.LogInformation($"DeleteItem with id {item}", item); var deleted = await _dataManager.DbContext.DeleteItem(item); if (deleted) _logger.LogInformation($"Deleted user with ID {item}"); else _logger.LogWarning($"No user found with ID {item}"); return await Task.FromResult(deleted); } public async Task GetNbItems() { _logger.LogInformation("GetNbItems"); var nbItems = await _dataManager.DbContext.AthletesSet.CountAsync(); _logger.LogInformation($"Retrieved {nbItems} users"); return await Task.FromResult(nbItems); } public async Task> GetAllAthletes(int index, int count, AthleteOrderCriteria? criteria, bool descending = false) { _logger.LogInformation($"GetAllAthletes with index {index} and count {count}", index, count); _logger.LogInformation($"GetAllAthletes with criteria {criteria} and descending {descending}", criteria, descending); var athletes = _dataManager.DbContext.AthletesSet.IncludeStandardProperties() .GetItemsWithFilterAndOrdering(a => a.IsCoach == false, index, count, criteria != AthleteOrderCriteria.None ? criteria : null, descending).ToModels(); _logger.LogInformation($"Retrieved {athletes.Count()} athletes"); return await Task.FromResult(athletes); } public async Task> GetAllCoaches(int index, int count, AthleteOrderCriteria? criteria, bool descending = false) { _logger.LogInformation($"GetAllCoaches with index {index} and count {count}", index, count); _logger.LogInformation($"GetAllCoaches with criteria {criteria} and descending {descending}", criteria, descending); var coaches = _dataManager.DbContext.AthletesSet.IncludeStandardProperties() .GetItemsWithFilterAndOrdering(a => a.IsCoach, index, count, criteria != AthleteOrderCriteria.None ? criteria : null, descending).ToModels(); _logger.LogInformation($"Retrieved {coaches.Count()} coaches"); return await Task.FromResult(coaches); } public async Task AddFriend(User user, User friend) { _logger.LogInformation($"Attempting to add friend: User {user.Id} adding Friend {friend.Id}"); var userEntity = _dataManager.DbContext.AthletesSet.IncludeStandardProperties().FirstOrDefault(a => a.IdAthlete == user.Id); var friendEntity = _dataManager.DbContext.AthletesSet.IncludeStandardProperties().FirstOrDefault(a => a.IdAthlete == friend.Id); if (userEntity == null || friendEntity == null) { _logger.LogWarning($"User or friend not found: User {user.Id}, Friend {friend.Id}"); return false; } if (userEntity.Followings.All(f => f.FollowingId != friend.Id)) { userEntity.Followings.Add(new FriendshipEntity { FollowingId = friend.Id, FollowerId = user.Id, StartDate = DateTime.Now }); await _dataManager.DbContext.SaveChangesAsync(); _logger.LogInformation($"Successfully added friend: User {user.Id} added Friend {friend.Id}"); return true; } _logger.LogInformation($"Friendship already exists: User {user.Id} and Friend {friend.Id}"); return false; } public async Task RemoveFriend(User user, User friend) { _logger.LogInformation($"Attempting to remove friend: User {user.Id} removing Friend {friend.Id}"); var userEntity = user.ToEntity(); var friendEntity = friend.ToEntity(); if (userEntity == null || friendEntity == null) { _logger.LogWarning($"User or friend not found: User {user.Id}, Friend {friend.Id}"); return false; } var friendship = userEntity.Followings.FirstOrDefault(f => f.FollowingId == friend.Id); if (friendship != null) { userEntity.Followings.Remove(friendship); await _dataManager.DbContext.SaveChangesAsync(); _logger.LogInformation($"Successfully removed friend: User {user.Id} removed Friend {friend.Id}"); return true; } _logger.LogInformation($"Friendship does not exist: User {user.Id} and Friend {friend.Id}"); return false; } public Task> GetFriends(User user, int index, int count, AthleteOrderCriteria? criteria, bool descending = false) { try { _logger.LogInformation($"GetFriends with index {index} and count {count}", index, count); _logger.LogInformation($"GetFriends with criteria {criteria} and descending {descending}", criteria, descending); var friends = _dataManager.DbContext.AthletesSet.IncludeStandardProperties() .GetItemsWithFilterAndOrdering(a => a.Followers.Any(f => f.FollowingId == user.Id), index, count, criteria, descending).ToModels(); _logger.LogInformation($"Retrieved {friends.Count()} friends"); return Task.FromResult(friends); } catch (Exception ex) { _logger.LogError(ex.Message, ex.InnerException, ex.StackTrace); return Task.FromResult>(new List()); } } public Task GetNbFriends(User user) { _logger.LogInformation($"GetNbFriends with user {user}", user); var nbFriends = _dataManager.DbContext.AthletesSet .GetItemsWithFilterAndOrdering(a => a.IdAthlete == user.Id, 0, int.MaxValue, AthleteOrderCriteria.None, false).First().Followings.Count(); _logger.LogInformation($"Retrieved {nbFriends} friends"); return Task.FromResult(nbFriends); } } }