// ReSharper disable ClassNeverInstantiated.Global namespace TeamCity.CSharpInteractive; using System.Collections; using System.Diagnostics.CodeAnalysis; using HostApi; internal class Properties : IProperties { private readonly ILog _log; private readonly Dictionary _props; public Properties( ILog log, ISettings settings) { _log = log; _props = new Dictionary(FilterPairs(settings.ScriptProperties)); } public int Count { get { lock (_props) { return _props.Count; } } } public string this[string key] { get => TryGetValue(key, out var value) ? value : string.Empty; set { lock (_props) { _log.Trace(() => new[] {new Text($"Props[\"{key}\"]=\"{value}\"")}); if (!string.IsNullOrEmpty(value)) { _props[key] = value; } else { _log.Trace(() => new[] {new Text($"Props.Remove(\"{key}\")")}); _props.Remove(key); } } } } public IEnumerator> GetEnumerator() { IReadOnlyList> props; lock (_props) { props = FilterPairs(_props).ToList().AsReadOnly(); } return props.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); public bool TryGetValue(string key, [MaybeNullWhen(false)] out string value) { lock (_props) { _props.TryGetValue(key, out var curValue); value = curValue ?? string.Empty; _log.Trace(() => new[] {new Text($"Props[\"{key}\"] returns \"{curValue ?? "empty"}\"")}); return !string.IsNullOrEmpty(value); } } private static IEnumerable> FilterPairs(IEnumerable> pairs) => pairs.Where(i => !string.IsNullOrWhiteSpace(i.Key) && !string.IsNullOrEmpty(i.Value)); }