using System; using System.Collections.Generic; using System.Linq; namespace SharpChat { public class ChannelsContext { private readonly List Channels = new(); public ChannelInfo? MainChannel { get; private set; } public int TotalCount { get; private set; } public int PublicCount { get; private set; } public ChannelInfo[] All => Channels.ToArray(); public ChannelInfo? Get( string? name, Func? sanitise = null ) { if(string.IsNullOrWhiteSpace(name)) return null; foreach(ChannelInfo info in Channels) { string chanName = info.Name; if(sanitise != null) chanName = sanitise(chanName); if(!chanName.Equals(name, StringComparison.InvariantCultureIgnoreCase)) continue; return info; } return null; } public ChannelInfo[] GetMany( string[]? names = null, Func? sanitiseName = null, int minRank = 0, bool? isPublic = null ) { List chans = new(); names ??= Array.Empty(); for(int i = 0; i < names.Length; ++i) names[i] = names[i].ToLowerInvariant(); foreach(ChannelInfo info in Channels) { if(info.Rank > minRank) continue; if(isPublic != null && info.IsPublic != isPublic) continue; if(names?.Length > 0) { string chanName = info.Name; if(sanitiseName != null) chanName = sanitiseName(chanName); bool match = false; foreach(string name in names) if(match = chanName.Equals(name, StringComparison.InvariantCultureIgnoreCase)) break; if(!match) continue; } chans.Add(info); } return chans.ToArray(); } public void Add( ChannelInfo info, bool forceMain = false, Func? sanitiseName = null ) { if(Get(info.Name, sanitiseName) != null) throw new ArgumentException("A channel with this name has already been registered.", nameof(info)); if(string.IsNullOrWhiteSpace(info.Name)) throw new ArgumentException("Channel names may not be blank.", nameof(info)); // todo: there should be more restrictions on channel names Channels.Add(info); ++TotalCount; if(info.IsPublic) ++PublicCount; if(forceMain || MainChannel == null) MainChannel = info; } public void Remove( ChannelInfo info, Func? sanitiseName = null ) { Remove(info.Name, sanitiseName); } public void Remove( string? name, Func? sanitise = null ) { if(string.IsNullOrWhiteSpace(name)) return; ChannelInfo? info = Get(name, sanitise); if(info == null) return; Channels.Remove(info); --TotalCount; if(info.IsPublic) --PublicCount; if(MainChannel == info) MainChannel = Channels.FirstOrDefault(c => !c.IsPublic); } } }