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 AddSeasonToCollectionHandler : MediatR.IRequestHandler> { private readonly IMediaCollectionRepository _mediaCollectionRepository; private readonly ITelevisionRepository _televisionRepository; public AddSeasonToCollectionHandler( IMediaCollectionRepository mediaCollectionRepository, ITelevisionRepository televisionRepository) { _mediaCollectionRepository = mediaCollectionRepository; _televisionRepository = televisionRepository; } public Task> Handle( AddSeasonToCollection request, CancellationToken cancellationToken) => Validate(request) .MapT(_ => ApplyAddTelevisionSeasonRequest(request)) .Bind(v => v.ToEitherAsync()); private async Task ApplyAddTelevisionSeasonRequest(AddSeasonToCollection request) => await _mediaCollectionRepository.AddMediaItem(request.CollectionId, request.SeasonId); private async Task> Validate(AddSeasonToCollection request) => (await CollectionMustExist(request), await ValidateSeason(request)) .Apply((_, _) => Unit.Default); private Task> CollectionMustExist(AddSeasonToCollection request) => _mediaCollectionRepository.GetCollectionWithItems(request.CollectionId) .MapT(_ => Unit.Default) .Map(v => v.ToValidation("Collection does not exist.")); private Task> ValidateSeason(AddSeasonToCollection request) => LoadTelevisionSeason(request) .MapT(_ => Unit.Default) .Map(v => v.ToValidation("Season does not exist")); private Task> LoadTelevisionSeason( AddSeasonToCollection request) => _televisionRepository.GetSeason(request.SeasonId); } }