using System.Threading; using System.Threading.Tasks; using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Extensions; using LanguageExt; using MediatR; using Microsoft.EntityFrameworkCore; namespace ErsatzTV.Application.Watermarks.Commands { public class UpdateWatermarkHandler : IRequestHandler> { private readonly IDbContextFactory _dbContextFactory; public UpdateWatermarkHandler(IDbContextFactory dbContextFactory) => _dbContextFactory = dbContextFactory; public async Task> Handle( UpdateWatermark request, CancellationToken cancellationToken) { await using TvContext dbContext = _dbContextFactory.CreateDbContext(); Validation validation = await Validate(dbContext, request); return await validation.Apply(p => ApplyUpdateRequest(dbContext, p, request)); } private static async Task ApplyUpdateRequest( TvContext dbContext, ChannelWatermark p, UpdateWatermark update) { p.Name = update.Name; p.Image = update.ImageSource == ChannelWatermarkImageSource.Custom ? update.Image : null; p.Mode = update.Mode; p.ImageSource = update.ImageSource; p.Location = update.Location; p.Size = update.Size; p.WidthPercent = update.Width; p.HorizontalMarginPercent = update.HorizontalMargin; p.VerticalMarginPercent = update.VerticalMargin; p.FrequencyMinutes = update.FrequencyMinutes; p.DurationSeconds = update.DurationSeconds; p.Opacity = update.Opacity; await dbContext.SaveChangesAsync(); return new UpdateWatermarkResult(p.Id); } private static async Task> Validate( TvContext dbContext, UpdateWatermark request) => (await WatermarkMustExist(dbContext, request), ValidateName(request)) .Apply((watermark, _) => watermark); private static Task> WatermarkMustExist( TvContext dbContext, UpdateWatermark updateWatermark) => dbContext.ChannelWatermarks .SelectOneAsync(p => p.Id, p => p.Id == updateWatermark.Id) .Map(o => o.ToValidation("Watermark does not exist.")); private static Validation ValidateName(UpdateWatermark updateWatermark) => updateWatermark.NotEmpty(x => x.Name) .Bind(_ => updateWatermark.NotLongerThan(50)(x => x.Name)); } }