using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; namespace ErsatzTV.Application.Emby; public class UpdateEmbyPathReplacementsHandler : IRequestHandler> { private readonly IMediaSourceRepository _mediaSourceRepository; public UpdateEmbyPathReplacementsHandler(IMediaSourceRepository mediaSourceRepository) => _mediaSourceRepository = mediaSourceRepository; public Task> Handle( UpdateEmbyPathReplacements request, CancellationToken cancellationToken) => Validate(request) .MapT(pms => MergePathReplacements(request, pms)) .Bind(v => v.ToEitherAsync()); private Task MergePathReplacements( UpdateEmbyPathReplacements request, EmbyMediaSource embyMediaSource) { embyMediaSource.PathReplacements ??= new List(); var incoming = request.PathReplacements.Map(Project).ToList(); var toAdd = incoming.Filter(r => r.Id < 1).ToList(); var toRemove = embyMediaSource.PathReplacements.Filter(r => incoming.All(pr => pr.Id != r.Id)).ToList(); var toUpdate = incoming.Except(toAdd).ToList(); return _mediaSourceRepository.UpdatePathReplacements(embyMediaSource.Id, toAdd, toUpdate, toRemove); } private static EmbyPathReplacement Project(EmbyPathReplacementItem vm) => new() { Id = vm.Id, EmbyPath = vm.EmbyPath, LocalPath = vm.LocalPath }; private Task> Validate(UpdateEmbyPathReplacements request) => EmbyMediaSourceMustExist(request); private Task> EmbyMediaSourceMustExist( UpdateEmbyPathReplacements request) => _mediaSourceRepository.GetEmby(request.EmbyMediaSourceId) .Map( v => v.ToValidation( $"Emby media source {request.EmbyMediaSourceId} does not exist.")); }