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 LanguageExt; namespace ErsatzTV.Application.MediaCollections.Commands { public class AddArtistToCollectionHandler : MediatR.IRequestHandler> { private readonly IArtistRepository _artistRepository; private readonly ChannelWriter _channel; private readonly IMediaCollectionRepository _mediaCollectionRepository; public AddArtistToCollectionHandler( IMediaCollectionRepository mediaCollectionRepository, IArtistRepository artistRepository, ChannelWriter channel) { _mediaCollectionRepository = mediaCollectionRepository; _artistRepository = artistRepository; _channel = channel; } public Task> Handle( AddArtistToCollection request, CancellationToken cancellationToken) => Validate(request) .MapT(_ => ApplyAddArtistRequest(request)) .Bind(v => v.ToEitherAsync()); private async Task ApplyAddArtistRequest(AddArtistToCollection request) { if (await _mediaCollectionRepository.AddMediaItem(request.CollectionId, request.ArtistId)) { // 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 async Task> Validate(AddArtistToCollection request) => (await CollectionMustExist(request), await ValidateArtist(request)) .Apply((_, _) => Unit.Default); private Task> CollectionMustExist(AddArtistToCollection request) => _mediaCollectionRepository.GetCollectionWithItems(request.CollectionId) .MapT(_ => Unit.Default) .Map(v => v.ToValidation("Collection does not exist.")); private Task> ValidateArtist(AddArtistToCollection request) => LoadArtist(request) .MapT(_ => Unit.Default) .Map(v => v.ToValidation("Music video does not exist")); private Task> LoadArtist(AddArtistToCollection request) => _artistRepository.GetArtist(request.ArtistId); } }