using Microsoft.EntityFrameworkCore; using Modules.User.Database.Database; using Modules.User.Database.Database.Entities; using System.Diagnostics.CodeAnalysis; using System.Linq.Expressions; namespace Modules.User.Database.Repositories; public class SessionRepository(UserDbContext context) { private readonly UserDbContext _context = context; public async Task> GetAll(Guid accountId) => await _context.Sessions.Where(q => q.AccountId == accountId).ToListAsync(); public async Task GetFirstOrDefaultWhere(Expression> predicate) => await _context.Sessions.SingleOrDefaultAsync(predicate); public async Task SyncSessions(Guid accountId, IEnumerable sessions) { var accountSessions = await GetAll(accountId); var deleteSessions = accountSessions.Except(sessions, new SessionComparer()).ToList(); var addSessions = sessions.Except(accountSessions, new SessionComparer()); var updateSessions = sessions.Where(q => accountSessions.Any(x => x.Id == q.Id && x.AccountId == q.AccountId)); var result = true; if (deleteSessions.Any()) { foreach(var session in deleteSessions) { _context.Sessions.Remove(accountSessions.First(q => q.Id == session.Id)); } } if (addSessions.Any() && result) { _context.Sessions.AddRange(addSessions); } if (updateSessions.Any() && result) { foreach (var session in updateSessions) { var existingSession = accountSessions.First(q => q.Id == session.Id); existingSession.ClientInfo = new() { UserAgent = session.ClientInfo.UserAgent, Country = session.ClientInfo.Country, Region = session.ClientInfo.Region, }; existingSession.RefreshToken = session.RefreshToken; existingSession.ExpiredDate = session.ExpiredDate;; } } await _context.SaveChangesAsync(); return result; } private class SessionComparer : IEqualityComparer { public bool Equals(Session? x, Session? y) { return x != null && y != null && x.Id != default && y.Id != default && x.Id == y.Id && x.AccountId == y.AccountId; } public int GetHashCode([DisallowNull] Session obj) { return HashCode.Combine(obj.Id.GetHashCode(), obj.AccountId.GetHashCode()); } } //public async Task DeleteAsync(Session entity, bool cleanExpired = true) //{ // var document = await _collection.FindOneAndDeleteAsync(q => q.RefreshToken == entity.RefreshToken); // if (cleanExpired) await CleanAccountSessions(entity.AccountId); // return document != null; //} //public async Task CleanAccountSessions(Guid accountId) => await DeleteAccountSessions(accountId); //private async Task DeleteAccountSessions(Guid accountId, bool onlyExpired = true) //{ // var filter = Builders.Filter.Eq(q => q.AccountId, accountId); // if (onlyExpired) filter = filter & Builders.Filter.Lt(q => q.ExpiredDate, DateTime.UtcNow); // var deleteResult = await _collection.DeleteManyAsync(filter); // return deleteResult.IsAcknowledged; //} }