using System.IO.Abstractions; using System.Threading.Channels; using ErsatzTV.Core; using ErsatzTV.Core.Interfaces.Search; using ErsatzTV.Infrastructure.Data; using ErsatzTV.Infrastructure.Extensions; using Microsoft.EntityFrameworkCore; using Channel = ErsatzTV.Core.Domain.Channel; namespace ErsatzTV.Application.Channels; public class DeleteChannelHandler : IRequestHandler> { private readonly IDbContextFactory _dbContextFactory; private readonly IFileSystem _fileSystem; private readonly ISearchTargets _searchTargets; private readonly ChannelWriter _workerChannel; public DeleteChannelHandler( ChannelWriter workerChannel, IDbContextFactory dbContextFactory, IFileSystem fileSystem, ISearchTargets searchTargets) { _workerChannel = workerChannel; _dbContextFactory = dbContextFactory; _fileSystem = fileSystem; _searchTargets = searchTargets; } public async Task> Handle(DeleteChannel request, CancellationToken cancellationToken) { await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken); Validation validation = await ChannelMustExist(dbContext, request, cancellationToken); return await validation.Apply(c => DoDeletion(dbContext, c, cancellationToken)); } private async Task DoDeletion(TvContext dbContext, Channel channel, CancellationToken cancellationToken) { dbContext.Channels.Remove(channel); await dbContext.SaveChangesAsync(cancellationToken); _searchTargets.SearchTargetsChanged(); // delete channel data from channel guide cache string cacheFile = Path.Combine(FileSystemLayout.ChannelGuideCacheFolder, $"{channel.Number}.xml"); if (_fileSystem.File.Exists(cacheFile)) { File.Delete(cacheFile); } // refresh channel list to remove channel that has no playout await _workerChannel.WriteAsync(new RefreshChannelList(), cancellationToken); return Unit.Default; } private static async Task> ChannelMustExist( TvContext dbContext, DeleteChannel deleteChannel, CancellationToken cancellationToken) { Option maybeChannel = await dbContext.Channels .SelectOneAsync(c => c.Id, c => c.Id == deleteChannel.ChannelId, cancellationToken); return maybeChannel.ToValidation($"Channel {deleteChannel.ChannelId} does not exist."); } }