using System; using System.Collections.Generic; using System.Linq; using CTA.FeatureDetection.Common.Models.Features.Base; using Microsoft.Extensions.Logging; namespace CTA.FeatureDetection.Common.Models.Features { /// /// A set of features that will bw looked for by the FeatureDetector class. /// These features are separated into Compiled and Configured features. /// public class FeatureSet { private const string FeatureNameConflictTemplate = "Feature with name {0} already exists in set of {1} features."; private ILogger Logger => Log.Logger; public HashSet CompiledFeatures { get; set; } public HashSet ConfiguredFeatures { get; set; } public HashSet AllFeatures => CompiledFeatures.Concat(ConfiguredFeatures).ToHashSet(); public FeatureSet() { CompiledFeatures = new HashSet(); ConfiguredFeatures = new HashSet(); } public FeatureSet(IEnumerable compiledFeatures, IEnumerable configuredFeatures) { CompiledFeatures = compiledFeatures.ToHashSet(); ConfiguredFeatures = configuredFeatures.ToHashSet(); } public FeatureSet(IEnumerable compiledFeatures) { CompiledFeatures = compiledFeatures.ToHashSet(); ConfiguredFeatures = new HashSet(); } public FeatureSet(IEnumerable configuredFeatures) { CompiledFeatures = new HashSet(); ConfiguredFeatures = configuredFeatures.ToHashSet(); } public void UnionWith(FeatureSet featureSet) { Add(featureSet.ConfiguredFeatures); Add(featureSet.CompiledFeatures); } public void Add(IEnumerable features) { foreach (var feature in features) { try { Add(feature); } catch (Exception ex) { Logger.LogError(ex, ex.Message); } } } public void Add(Feature feature) { var featureType = feature.GetType(); if (feature is CompiledFeature compiledFeature) { if (ConfiguredFeatures.Any(f => f.Name == feature.Name)) { throw new ArgumentException(string.Format(FeatureNameConflictTemplate, feature.Name, nameof(ConfiguredFeature))); } CompiledFeatures.Add(compiledFeature); } else if (feature is ConfiguredFeature configuredFeature) { if (CompiledFeatures.Any(f => f.Name == feature.Name)) { throw new ArgumentException(string.Format(FeatureNameConflictTemplate, feature.Name, nameof(CompiledFeature))); } ConfiguredFeatures.Add(configuredFeature); } else { throw new NotImplementedException($"Support for {featureType} features in {nameof(FeatureSet)} has not been implemented."); } } } }