using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using ErsatzTV.Application.MediaItems; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using LanguageExt; using LanguageExt.UnsafeValueAccess; using MediatR; namespace ErsatzTV.Application.MediaCollections.Commands { public class ReplaceSimpleMediaCollectionItemsHandler : IRequestHandler>> { private readonly IMediaCollectionRepository _mediaCollectionRepository; private readonly IMediaItemRepository _mediaItemRepository; public ReplaceSimpleMediaCollectionItemsHandler( IMediaCollectionRepository mediaCollectionRepository, IMediaItemRepository mediaItemRepository) { _mediaCollectionRepository = mediaCollectionRepository; _mediaItemRepository = mediaItemRepository; } public Task>> Handle( ReplaceSimpleMediaCollectionItems request, CancellationToken cancellationToken) => Validate(request) .MapT(mediaItems => PersistItems(request, mediaItems)) .Bind(v => v.ToEitherAsync()); private async Task> PersistItems( ReplaceSimpleMediaCollectionItems request, List mediaItems) { await _mediaCollectionRepository.ReplaceItems(request.MediaCollectionId, mediaItems); return mediaItems.Map(MediaItems.Mapper.ProjectToViewModel).ToList(); } private Task>> Validate(ReplaceSimpleMediaCollectionItems request) => MediaCollectionMustExist(request).BindT(_ => MediaItemsMustExist(request)); private async Task> MediaCollectionMustExist( ReplaceSimpleMediaCollectionItems request) => (await _mediaCollectionRepository.GetSimpleMediaCollection(request.MediaCollectionId)) .ToValidation("[MediaCollectionId] does not exist."); private async Task>> MediaItemsMustExist( ReplaceSimpleMediaCollectionItems replaceItems) { var allMediaItems = (await replaceItems.MediaItemIds.Map(i => _mediaItemRepository.Get(i)).Sequence()) .ToList(); if (allMediaItems.Any(x => x.IsNone)) { return BaseError.New("[MediaItemId] does not exist"); } return allMediaItems.Sequence().ValueUnsafe().ToList(); } } }