using System.Threading; using System.Threading.Tasks; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using LanguageExt; namespace ErsatzTV.Application.MediaCollections.Commands { public class AddMovieToCollectionHandler : MediatR.IRequestHandler> { private readonly IMediaCollectionRepository _mediaCollectionRepository; private readonly IMovieRepository _movieRepository; public AddMovieToCollectionHandler( IMediaCollectionRepository mediaCollectionRepository, IMovieRepository movieRepository) { _mediaCollectionRepository = mediaCollectionRepository; _movieRepository = movieRepository; } public Task> Handle( AddMovieToCollection request, CancellationToken cancellationToken) => Validate(request) .MapT(_ => ApplyAddMoviesRequest(request)) .Bind(v => v.ToEitherAsync()); private Task ApplyAddMoviesRequest(AddMovieToCollection request) => _mediaCollectionRepository.AddMediaItem(request.CollectionId, request.MovieId); private async Task> Validate(AddMovieToCollection request) => (await CollectionMustExist(request), await ValidateMovies(request)) .Apply((_, _) => Unit.Default); private Task> CollectionMustExist(AddMovieToCollection request) => _mediaCollectionRepository.GetCollectionWithItems(request.CollectionId) .MapT(_ => Unit.Default) .Map(v => v.ToValidation("Collection does not exist.")); private Task> ValidateMovies(AddMovieToCollection request) => LoadMovie(request) .MapT(_ => Unit.Default) .Map(v => v.ToValidation("Movie does not exist")); private Task> LoadMovie(AddMovieToCollection request) => _movieRepository.GetMovie(request.MovieId); } }