using System.Linq; using System.Threading; using System.Threading.Channels; using System.Threading.Tasks; using ErsatzTV.Application.Playouts.Commands; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Extensions; using LanguageExt; using Microsoft.EntityFrameworkCore; namespace ErsatzTV.Application.MediaCollections.Commands { public class UpdateCollectionCustomOrderHandler : MediatR.IRequestHandler> { private readonly ChannelWriter _channel; private readonly IDbContextFactory _dbContextFactory; private readonly IMediaCollectionRepository _mediaCollectionRepository; public UpdateCollectionCustomOrderHandler( IDbContextFactory dbContextFactory, IMediaCollectionRepository mediaCollectionRepository, ChannelWriter channel) { _dbContextFactory = dbContextFactory; _mediaCollectionRepository = mediaCollectionRepository; _channel = channel; } public async Task> Handle( UpdateCollectionCustomOrder request, CancellationToken cancellationToken) { await using TvContext dbContext = _dbContextFactory.CreateDbContext(); Validation validation = await Validate(dbContext, request); return await validation.Apply(c => ApplyUpdateRequest(dbContext, c, request)); } private async Task ApplyUpdateRequest( TvContext dbContext, Collection c, UpdateCollectionCustomOrder request) { foreach (MediaItemCustomOrder updateItem in request.MediaItemCustomOrders) { Option maybeCollectionItem = c.CollectionItems .FirstOrDefault(ci => ci.MediaItemId == updateItem.MediaItemId); foreach (CollectionItem collectionItem in maybeCollectionItem) { collectionItem.CustomIndex = updateItem.CustomIndex; } } if (await dbContext.SaveChangesAsync() > 0) { // rebuild all playouts that use this collection foreach (int playoutId in await _mediaCollectionRepository .PlayoutIdsUsingCollection(request.CollectionId)) { await _channel.WriteAsync(new BuildPlayout(playoutId, true)); } } return Unit.Default; } private static Task> Validate( TvContext dbContext, UpdateCollectionCustomOrder request) => CollectionMustExist(dbContext, request); private static Task> CollectionMustExist( TvContext dbContext, UpdateCollectionCustomOrder request) => dbContext.Collections .Include(c => c.CollectionItems) .SelectOneAsync(c => c.Id, c => c.Id == request.CollectionId) .Map(o => o.ToValidation("Collection does not exist.")); } }