using System.Globalization; using System.Threading.Channels; using ErsatzTV.Application.Playouts; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Scheduling; using ErsatzTV.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace ErsatzTV.Application.Configuration; public class UpdatePlayoutSettingsHandler : IRequestHandler> { private readonly IConfigElementRepository _configElementRepository; private readonly IDbContextFactory _dbContextFactory; private readonly ChannelWriter _workerChannel; public UpdatePlayoutSettingsHandler( IConfigElementRepository configElementRepository, IDbContextFactory dbContextFactory, ChannelWriter workerChannel) { _configElementRepository = configElementRepository; _dbContextFactory = dbContextFactory; _workerChannel = workerChannel; } public async Task> Handle( UpdatePlayoutSettings request, CancellationToken cancellationToken) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken); Validation validation = await Validate(request); return await validation.Apply(_ => ApplyUpdate(dbContext, request.PlayoutSettings)); } private async Task ApplyUpdate(TvContext dbContext, PlayoutSettingsViewModel playoutSettings) { await _configElementRepository.Upsert(ConfigElementKey.PlayoutDaysToBuild, playoutSettings.DaysToBuild); await _configElementRepository.Upsert( ConfigElementKey.PlayoutSkipMissingItems, playoutSettings.SkipMissingItems); // continue 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, CultureInfo.InvariantCulture)) .Map(p => p.Id)) { await _workerChannel.WriteAsync(new BuildPlayout(playoutId, PlayoutBuildMode.Continue)); } return Unit.Default; } private static Task> Validate(UpdatePlayoutSettings request) => Optional(request.PlayoutSettings.DaysToBuild) .Where(days => days > 0) .Map(_ => Unit.Default) .ToValidation("Days to build must be greater than zero") .AsTask(); }