namespace SharpChat.Channels; public class ChannelsContext { private readonly List<Channel> Channels = []; public int Count => Channels.Count; private Channel? DefaultChannelValue; public Channel DefaultChannel { get { if(DefaultChannelValue is not null) { if(Channels.Contains(DefaultChannelValue)) return DefaultChannelValue; DefaultChannelValue = null; } return GetChannel(c => c.IsPublic && !c.IsTemporary) ?? throw new NoDefaultChannelException(); } set => DefaultChannelValue = value; } public bool ChannelExists(Func<Channel, bool> predicate) { return Channels.Any(predicate); } public bool ChannelExists(string name) { return ChannelExists(c => c.NameEquals(name)); } public Channel? GetChannel(Func<Channel, bool> predicate) { return Channels.FirstOrDefault(predicate); } public Channel? GetChannel(string name) { return GetChannel(c => c.NameEquals(name)); } public IEnumerable<Channel> GetChannels(Func<Channel, bool> predicate) { return Channels.Where(predicate); } public IEnumerable<Channel> GetChannels(IEnumerable<string> names) { return GetChannels(c => names.Any(n => c.NameEquals(n))); } public IEnumerable<Channel> GetChannels(int maxRank) { return GetChannels(c => c.Rank <= maxRank); } public Channel CreateChannel( string name, string password = "", bool temporary = false, int rank = 0, string ownerId = "" ) { if(!Channel.CheckName(name)) throw new ChannelNameFormatException(nameof(name)); if(ChannelExists(name)) throw new ChannelExistsException(nameof(name)); Channel channel = new( name, password ?? string.Empty, temporary, rank, ownerId ?? string.Empty ); Channels.Add(channel); return channel; } public Channel UpdateChannel( Channel channel, string? name = null, string? password = null, bool? temporary = null, int? rank = null, string? ownerId = null ) => UpdateChannel(channel.Name, name, password, temporary, rank, ownerId); public Channel UpdateChannel( string currentName, string? name = null, string? password = null, bool? temporary = null, int? rank = null, string? ownerId = null ) { Channel channel = GetChannel(currentName) ?? throw new ChannelNotFoundException(nameof(currentName)); if(name is not null && currentName != name) { if(!Channel.CheckName(name)) throw new ChannelNameFormatException(nameof(name)); if(ChannelExists(name)) throw new ChannelExistsException(nameof(name)); } if(name is not null) channel.Name = name; if(password is not null) channel.Password = password; if(temporary.HasValue) channel.IsTemporary = temporary.Value; if(rank.HasValue) channel.Rank = rank.Value; if(ownerId is not null) channel.OwnerId = ownerId; return channel; } public void RemoveChannel(string name) { Channel channel = GetChannel(name) ?? throw new ChannelNotFoundException(nameof(name)); Channel defaultChannel = DefaultChannel; if(channel == defaultChannel || defaultChannel.NameEquals(channel.Name)) throw new ChannelIsDefaultException(nameof(name)); Channels.Remove(channel); } }