using System.IO; using System.Threading; using System.Threading.Tasks; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Metadata; using ErsatzTV.Core.Interfaces.Repositories; using LanguageExt; using static LanguageExt.Prelude; namespace ErsatzTV.Application.MediaItems.Commands { public class RefreshMediaItemStatisticsHandler : MediatR.IRequestHandler> { private readonly IConfigElementRepository _configElementRepository; private readonly ILocalStatisticsProvider _localStatisticsProvider; private readonly IMediaItemRepository _mediaItemRepository; public RefreshMediaItemStatisticsHandler( IMediaItemRepository mediaItemRepository, IConfigElementRepository configElementRepository, ILocalStatisticsProvider localStatisticsProvider) { _mediaItemRepository = mediaItemRepository; _configElementRepository = configElementRepository; _localStatisticsProvider = localStatisticsProvider; } public Task> Handle( RefreshMediaItemStatistics request, CancellationToken cancellationToken) => Validate(request) .MapT(RefreshStatistics) .Bind(v => v.ToEitherAsync()); private async Task> Validate(RefreshMediaItemStatistics request) => (await MediaItemMustExist(request).BindT(PathMustExist), await ValidateFFprobePath()) .Apply((mediaItem, ffprobePath) => new RefreshParameters(mediaItem, ffprobePath)); private Task> MediaItemMustExist( RefreshMediaItemStatistics refreshMediaItemStatistics) => _mediaItemRepository.Get(refreshMediaItemStatistics.MediaItemId) .Map( maybeItem => maybeItem.ToValidation( $"[MediaItem] {refreshMediaItemStatistics.MediaItemId} does not exist.")); private Validation PathMustExist(MediaItem mediaItem) => Some(mediaItem) .Filter(item => File.Exists(item.Path)) .ToValidation($"[Path] '{mediaItem.Path}' does not exist on the file system"); private Task> ValidateFFprobePath() => _configElementRepository.GetValue(ConfigElementKey.FFprobePath) .FilterT(File.Exists) .Map( ffprobePath => ffprobePath.ToValidation("FFprobe path does not exist on the file system")); private Task RefreshStatistics(RefreshParameters parameters) => _localStatisticsProvider.RefreshStatistics(parameters.FFprobePath, parameters.MediaItem).ToUnit(); private record RefreshParameters(MediaItem MediaItem, string FFprobePath); } }