using System; using Microsoft.Extensions.Options; namespace LightlessSyncServer.Configuration; public class BroadcastConfiguration : IBroadcastConfiguration { private static readonly TimeSpan DefaultEntryTtl = TimeSpan.FromMinutes(180); private const int DefaultMaxStatusBatchSize = 30; private const string DefaultNotificationTemplate = "{DisplayName} sent you a pair request. To accept, right-click them, open the context menu, and send a request back."; private readonly IOptionsMonitor _optionsMonitor; public BroadcastConfiguration(IOptionsMonitor optionsMonitor) { _optionsMonitor = optionsMonitor; } private BroadcastOptions Options => _optionsMonitor.CurrentValue ?? new BroadcastOptions(); public string RedisKeyPrefix { get { var prefix = Options.RedisKeyPrefix; return string.IsNullOrWhiteSpace(prefix) ? "broadcast:" : prefix!; } } public TimeSpan BroadcastEntryTtl { get { var seconds = Options.EntryTtlSeconds; return seconds > 0 ? TimeSpan.FromSeconds(seconds) : DefaultEntryTtl; } } public int MaxStatusBatchSize { get { var value = Options.MaxStatusBatchSize; return value > 0 ? value : DefaultMaxStatusBatchSize; } } public bool NotifyOwnerOnPairRequest => Options.NotifyOwnerOnPairRequest; public bool EnableBroadcasting => Options.EnableBroadcasting; public bool EnableSyncshellBroadcastPayloads => Options.EnableSyncshellBroadcastPayloads; public string BuildRedisKey(string hashedCid) { if (string.IsNullOrEmpty(hashedCid)) return RedisKeyPrefix; return string.Concat(RedisKeyPrefix, hashedCid); } public string BuildUserOwnershipKey(string userUid) { if (string.IsNullOrWhiteSpace(userUid)) throw new ArgumentException("User UID must not be null or empty.", nameof(userUid)); return string.Concat(RedisKeyPrefix, "owner:", userUid); } public string BuildPairRequestNotification() { var template = Options.PairRequestNotificationTemplate; if (string.IsNullOrWhiteSpace(template)) { template = DefaultNotificationTemplate; } return template; } public int PairRequestRateLimit => Options.PairRequestRateLimit > 0 ? Options.PairRequestRateLimit : 5; public int PairRequestRateWindow => Options.PairRequestRateWindow > 0 ? Options.PairRequestRateWindow : 60; }