using System; using System.Diagnostics; using System.IO; using System.Threading; using System.Threading.Tasks; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using LanguageExt; using MediatR; using static LanguageExt.Prelude; namespace ErsatzTV.Application.Streaming.Queries { public abstract class FFmpegProcessHandler : IRequestHandler> where T : FFmpegProcessRequest { private readonly IChannelRepository _channelRepository; private readonly IConfigElementRepository _configElementRepository; protected FFmpegProcessHandler( IChannelRepository channelRepository, IConfigElementRepository configElementRepository) { _channelRepository = channelRepository; _configElementRepository = configElementRepository; } public Task> Handle(T request, CancellationToken cancellationToken) => Validate(request) .Map(v => v.ToEither>()) .BindT(tuple => GetProcess(request, tuple.Item1, tuple.Item2)); protected abstract Task> GetProcess(T request, Channel channel, string ffmpegPath); private async Task>> Validate(T request) => (await ChannelMustExist(request), await FFmpegPathMustExist()) .Apply((channel, ffmpegPath) => Tuple(channel, ffmpegPath)); private async Task> ChannelMustExist(T request) => (await _channelRepository.GetByNumber(request.ChannelNumber)) .ToValidation($"Channel number {request.ChannelNumber} does not exist."); private Task> FFmpegPathMustExist() => _configElementRepository.GetValue(ConfigElementKey.FFmpegPath) .FilterT(File.Exists) .Map(maybePath => maybePath.ToValidation("FFmpeg path does not exist on filesystem")); } }