sharp-chat/SharpChatCommon/ChannelsContext.cs

124 lines
3.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
namespace SharpChat {
public class ChannelsContext {
private readonly List<ChannelInfo> 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<string, string>? 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<string, string>? sanitiseName = null,
int minRank = 0,
bool? isPublic = null
) {
List<ChannelInfo> chans = new();
names ??= Array.Empty<string>();
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<string, string>? 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<string, string>? sanitiseName = null
) {
Remove(info.Name, sanitiseName);
}
public void Remove(
string? name,
Func<string, string>? 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);
}
}
}