using ErsatzTV.Core; using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Infrastructure.Data; using Microsoft.EntityFrameworkCore; namespace ErsatzTV.Application.Watermarks; public class CreateWatermarkHandler : IRequestHandler> { private readonly IDbContextFactory _dbContextFactory; private readonly ISearchTargets _searchTargets; public CreateWatermarkHandler(IDbContextFactory dbContextFactory, ISearchTargets searchTargets) { _dbContextFactory = dbContextFactory; _searchTargets = searchTargets; } public async Task> Handle( CreateWatermark request, CancellationToken cancellationToken) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken); Validation validation = Validate(request); return await validation.Apply(profile => PersistChannelWatermark(dbContext, profile)); } private async Task PersistChannelWatermark( TvContext dbContext, ChannelWatermark watermark) { await dbContext.ChannelWatermarks.AddAsync(watermark); await dbContext.SaveChangesAsync(); _searchTargets.SearchTargetsChanged(); return new CreateWatermarkResult(watermark.Id); } private static Validation Validate(CreateWatermark request) => ValidateName(request) .Map( _ => new ChannelWatermark { Name = request.Name, Image = request.ImageSource == ChannelWatermarkImageSource.Custom ? request.Image : null, Mode = request.Mode, ImageSource = request.ImageSource, Location = request.Location, Size = request.Size, WidthPercent = request.Width, HorizontalMarginPercent = request.HorizontalMargin, VerticalMarginPercent = request.VerticalMargin, FrequencyMinutes = request.FrequencyMinutes, DurationSeconds = request.DurationSeconds, Opacity = request.Opacity, PlaceWithinSourceContent = request.PlaceWithinSourceContent }); private static Validation ValidateName(CreateWatermark request) => request.NotEmpty(x => x.Name) .Bind(_ => request.NotLongerThan(50)(x => x.Name)); }