using System.Threading.Channels; using ErsatzTV.Core; using ErsatzTV.Core.Interfaces.Jellyfin; using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Jellyfin; namespace ErsatzTV.Application.Jellyfin; public class SaveJellyfinSecretsHandler : IRequestHandler> { private readonly ChannelWriter _channel; private readonly IJellyfinApiClient _jellyfinApiClient; private readonly IJellyfinSecretStore _jellyfinSecretStore; private readonly IMediaSourceRepository _mediaSourceRepository; public SaveJellyfinSecretsHandler( IJellyfinSecretStore jellyfinSecretStore, IJellyfinApiClient jellyfinApiClient, IMediaSourceRepository mediaSourceRepository, ChannelWriter channel) { _jellyfinSecretStore = jellyfinSecretStore; _jellyfinApiClient = jellyfinApiClient; _mediaSourceRepository = mediaSourceRepository; _channel = channel; } public Task> Handle(SaveJellyfinSecrets request, CancellationToken cancellationToken) => Validate(request) .MapT(PerformSave) .Bind(v => v.ToEitherAsync()); private async Task> Validate(SaveJellyfinSecrets request) { Either maybeServerInformation = await _jellyfinApiClient .GetServerInformation(request.Secrets.Address, request.Secrets.ApiKey); return maybeServerInformation.Match( info => Validation.Success(new Parameters(request.Secrets, info)), error => error); } private async Task PerformSave(Parameters parameters) { await _jellyfinSecretStore.SaveSecrets(parameters.Secrets); await _mediaSourceRepository.UpsertJellyfin( parameters.Secrets.Address, parameters.ServerInformation.ServerName, parameters.ServerInformation.OperatingSystem); await _channel.WriteAsync(new SynchronizeJellyfinMediaSources()); return Unit.Default; } private sealed record Parameters(JellyfinSecrets Secrets, JellyfinServerInformation ServerInformation); }