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.");
}
}
}
}