using System.Collections.Immutable; using Luna.Channels.Abstractions; using Luna.Core.Abstractions; using Microsoft.Extensions.Logging; namespace Luna.Channels; public class ChannelManager(ISessionManager sessionManager, ILogger logger) : IChannelManager { private readonly Dictionary channels = new(); private readonly Dictionary sessionMap = new(); public event EventHandler? MessageRouted; public void RegisterChannel(IChannel channel) { if (!channels.TryAdd(channel.ChannelId, channel)) throw new InvalidOperationException($"Channel with id {channel.ChannelId} is already registered."); channel.MessageReceived += OnMessageReceivedAsync; } public void UnregisterChannel(string channelId) { if (!channels.TryGetValue(channelId, out var channel)) return; channel.MessageReceived -= OnMessageReceivedAsync; channels.Remove(channelId); } public IChannel? GetChannel(string channelId) { channels.TryGetValue(channelId, out var channel); return channel; } public IReadOnlyList GetAllChannels() => channels.Values.ToImmutableList(); private async Task OnMessageReceivedAsync(object? sender, ChannelMessageReceivedEventArgs args) { if (args.IsHandled) return; var channel = args.Channel; var message = args.Message; try { var response = sessionManager .RouteMessagesAsync(message.Content, message.ConversationId, channel.ChannelId); await channel.SendStreamingMessageAsync(response); MessageRouted?.Invoke(this, args); } catch (Exception exception) { logger.LogError(exception, "Message routing for channel of type {Type} with id {Id} failed", channel.ChannelType, channel.ChannelId); } } }