using System.Configuration; using LANCommander.Server.Data; using LANCommander.Server.Data.Models; using Microsoft.Extensions.Logging; using AutoMapper; using LANCommander.Server.Services.Extensions; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using ZiggyCreatures.Caching.Fusion; namespace LANCommander.Server.Services { public sealed class LibraryService( ILogger logger, SettingsProvider settingsProvider, IFusionCache cache, IMapper mapper, IHttpContextAccessor httpContextAccessor, IDbContextFactory contextFactory, GameService gameService, UserService userService) : BaseDatabaseService(logger, settingsProvider, cache, mapper, httpContextAccessor, contextFactory) { public override async Task AddAsync(Library entity) { return await base.AddAsync(entity, async context => { await context.UpdateRelationshipAsync(l => l.Games); await context.UpdateRelationshipAsync(l => l.User); }); } public override async Task UpdateAsync(Library entity) { return await base.UpdateAsync(entity, async context => { await context.UpdateRelationshipAsync(l => l.Games); await context.UpdateRelationshipAsync(l => l.User); }); } public async Task GetByUserIdAsync(Guid userId) { var library = await Include(l => l.Games).FirstOrDefaultAsync(l => l.User.Id == userId); if (library == null) { var user = await userService.GetAsync(userId); if (user == null) throw new Exception("User not found with ID " + userId.ToString()); library = await AddAsync(new Library { UserId = userId }); } return library; } public async Task AddToLibraryAsync(Guid userId, Guid gameId) { var game = await gameService.GetAsync(gameId); var library = await GetByUserIdAsync(userId); library.Games.Add(game); await UpdateAsync(library); await cache.RemoveByTagAsync([$"Library/{userId}"]); if (game.BaseGame != null && !library.Games.Any(g => g.Id == game.BaseGame.Id) && game.BaseGame.Id != game.Id) await AddToLibraryAsync(userId, game.BaseGame.Id); } public Task RemoveFromLibraryAsync(Guid userId, Guid gameId) { return RemoveFromLibraryAsync(userId, gameId, addonIds: []); } public async Task RemoveFromLibraryAsync(Guid userId, Guid gameId, Guid[] addonIds) { var library = await GetByUserIdAsync(userId); var game = library.Games.FirstOrDefault(g => g.Id == gameId); if (game != null && game.DependentGames != null && game.DependentGames.Any()) { addonIds ??= []; foreach (var dependentGame in game.DependentGames) { if (dependentGame.IsAddon || addonIds.Contains(dependentGame.Id)) { if (library.Games.Any(g => g.Id == dependentGame.Id) && dependentGame.Id != game.Id) library.Games.Remove(dependentGame); } } } library.Games.Remove(game!); await UpdateAsync(library); await cache.RemoveByTagAsync([$"Library/{userId}"]); } } }