using System.Linq;
using AnyOfTypes;
using JetBrains.Annotations;
using SimMetrics.Net;
using SimMetrics.Net.API;
using SimMetrics.Net.Metric;
using WireMock.Extensions;
using WireMock.Models;
using Stef.Validation;
namespace WireMock.Matchers
{
///
/// SimMetricsMatcher
///
///
public class SimMetricsMatcher : IStringMatcher
{
private readonly AnyOf[] _patterns;
private readonly SimMetricType _simMetricType;
///
public MatchBehaviour MatchBehaviour { get; }
///
public bool ThrowException { get; }
///
/// Initializes a new instance of the class.
///
/// The pattern.
/// The SimMetric Type
public SimMetricsMatcher([NotNull] AnyOf pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(new[] { pattern }, simMetricType)
{
}
///
/// Initializes a new instance of the class.
///
/// The match behaviour.
/// The pattern.
/// The SimMetric Type
public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] AnyOf pattern, SimMetricType simMetricType = SimMetricType.Levenstein) : this(matchBehaviour, new[] { pattern }, simMetricType)
{
}
///
/// Initializes a new instance of the class.
///
/// The patterns.
/// The SimMetric Type
public SimMetricsMatcher([NotNull] string[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns.ToAnyOfPatterns(), simMetricType)
{
}
///
/// Initializes a new instance of the class.
///
/// The patterns.
/// The SimMetric Type
public SimMetricsMatcher([NotNull] AnyOf[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein) : this(MatchBehaviour.AcceptOnMatch, patterns, simMetricType)
{
}
///
/// Initializes a new instance of the class.
///
/// The match behaviour.
/// The patterns.
/// The SimMetric Type
/// Throw an exception when the internal matching fails because of invalid input.
public SimMetricsMatcher(MatchBehaviour matchBehaviour, [NotNull] AnyOf[] patterns, SimMetricType simMetricType = SimMetricType.Levenstein, bool throwException = false)
{
Guard.NotNull(patterns, nameof(patterns));
MatchBehaviour = matchBehaviour;
ThrowException = throwException;
_patterns = patterns;
_simMetricType = simMetricType;
}
///
public double IsMatch(string input)
{
IStringMetric stringMetricType = GetStringMetricType();
return MatchBehaviourHelper.Convert(MatchBehaviour, MatchScores.ToScore(_patterns.Select(p => stringMetricType.GetSimilarity(p.GetPattern(), input))));
}
private IStringMetric GetStringMetricType()
{
switch (_simMetricType)
{
case SimMetricType.BlockDistance:
return new BlockDistance();
case SimMetricType.ChapmanLengthDeviation:
return new ChapmanLengthDeviation();
case SimMetricType.CosineSimilarity:
return new CosineSimilarity();
case SimMetricType.DiceSimilarity:
return new DiceSimilarity();
case SimMetricType.EuclideanDistance:
return new EuclideanDistance();
case SimMetricType.JaccardSimilarity:
return new JaccardSimilarity();
case SimMetricType.Jaro:
return new Jaro();
case SimMetricType.JaroWinkler:
return new JaroWinkler();
case SimMetricType.MatchingCoefficient:
return new MatchingCoefficient();
case SimMetricType.MongeElkan:
return new MongeElkan();
case SimMetricType.NeedlemanWunch:
return new NeedlemanWunch();
case SimMetricType.OverlapCoefficient:
return new OverlapCoefficient();
case SimMetricType.QGramsDistance:
return new QGramsDistance();
case SimMetricType.SmithWaterman:
return new SmithWaterman();
case SimMetricType.SmithWatermanGotoh:
return new SmithWatermanGotoh();
case SimMetricType.SmithWatermanGotohWindowedAffine:
return new SmithWatermanGotohWindowedAffine();
case SimMetricType.ChapmanMeanLength:
return new ChapmanMeanLength();
default:
return new Levenstein();
}
}
///
public AnyOf[] GetPatterns()
{
return _patterns;
}
///
public string Name => $"SimMetricsMatcher.{_simMetricType}";
}
}