using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Channels; using System.Threading.Tasks; using ErsatzTV.Application.Playouts.Commands; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Infrastructure.Data; using LanguageExt; using Microsoft.EntityFrameworkCore; using static LanguageExt.Prelude; namespace ErsatzTV.Application.Configuration.Commands { public class UpdatePlayoutDaysToBuildHandler : MediatR.IRequestHandler> { private readonly IConfigElementRepository _configElementRepository; private readonly IDbContextFactory _dbContextFactory; private readonly ChannelWriter _workerChannel; public UpdatePlayoutDaysToBuildHandler( IConfigElementRepository configElementRepository, IDbContextFactory dbContextFactory, ChannelWriter workerChannel) { _configElementRepository = configElementRepository; _dbContextFactory = dbContextFactory; _workerChannel = workerChannel; } public async Task> Handle( UpdatePlayoutDaysToBuild request, CancellationToken cancellationToken) { await using TvContext dbContext = _dbContextFactory.CreateDbContext(); Validation validation = await Validate(request); return await validation.Apply(_ => ApplyUpdate(dbContext, request.DaysToBuild)); } private async Task ApplyUpdate(TvContext dbContext, int daysToBuild) { await _configElementRepository.Upsert(ConfigElementKey.PlayoutDaysToBuild, daysToBuild); // build all playouts to proper number of days List playouts = await dbContext.Playouts .Include(p => p.Channel) .ToListAsync(); foreach (int playoutId in playouts.OrderBy(p => decimal.Parse(p.Channel.Number)).Map(p => p.Id)) { await _workerChannel.WriteAsync(new BuildPlayout(playoutId)); } return Unit.Default; } private static Task> Validate(UpdatePlayoutDaysToBuild request) => Optional(request.DaysToBuild) .Where(days => days > 0) .Map(_ => Unit.Default) .ToValidation("Days to build must be greater than zero") .AsTask(); } }