using System;
using System.Collections.Generic;
using System.Linq;
namespace DelftTools.Utils.Validation
{
public class ValidationReport
{
///
/// Gets the severity of the report, eg the maximum severity of any of its issues.
///
public ValidationSeverity Severity { get; private set; }
public string Category { get; private set; }
public IEnumerable Issues { get; private set; }
public IEnumerable SubReports { get; private set; }
public ValidationReport(string category, IEnumerable issues, IEnumerable subReports = null)
{
Category = category;
Issues = AsList(issues ?? new ValidationIssue[0]);
SubReports = AsList(subReports ?? new ValidationReport[0]);
Severity = DetermineSeverity();
}
public ValidationReport(string category, IEnumerable subReports)
: this(category, null, subReports)
{
}
///
/// Creates an empty validation report. Validation reports are read-only so they cannot be added to.
///
public static ValidationReport Empty(string name)
{
return new ValidationReport(name, null);
}
///
/// IsEmpty is true when the report contains no issues and no subreports
///
public bool IsEmpty
{
get { return !Issues.Any() && !SubReports.Any(); }
}
public IList GetAllIssuesRecursive()
{
var allIssues = new List();
allIssues.AddRange(Issues);
foreach(var report in SubReports)
{
allIssues.AddRange(report.GetAllIssuesRecursive());
}
return allIssues;
}
public IEnumerable AllErrors
{
get { return GetAllIssuesRecursive().Where(i => i.Severity == ValidationSeverity.Error); }
}
private ValidationSeverity DetermineSeverity()
{
var issueMax = Issues.Any() ? Issues.Max(i => i.Severity) : ValidationSeverity.None;
var reportMax = SubReports.Any() ? SubReports.Max(i => i.Severity) : ValidationSeverity.None;
return (ValidationSeverity) Math.Max((int) issueMax, (int) reportMax);
}
///
/// The total number of issues (recursive) with severity level 'Error'
///
public int ErrorCount
{
get { return GetIssueCount(ValidationSeverity.Error); }
}
///
/// The total number of issues (recursive) with severity level 'Warning'
///
public int WarningCount
{
get { return GetIssueCount(ValidationSeverity.Warning); }
}
///
/// The total number of issues (recursive) with severity level 'Info'
///
public int InfoCount
{
get { return GetIssueCount(ValidationSeverity.Info); }
}
private int GetIssueCount(ValidationSeverity severity)
{
return SubReports.Sum(r => r.GetIssueCount(severity)) + Issues.Count(i => i.Severity == severity);
}
public override bool Equals(object obj)
{
if (obj is ValidationReport)
{
return Equals(obj as ValidationReport);
}
return false;
}
public bool Equals(ValidationReport other)
{
if (other == null)
return false;
if (ReferenceEquals(this, other))
return true;
if (!Category.Equals(other.Category))
return false;
var issues = Issues.ToList();
var otherIssues = other.Issues.ToList();
if (issues.Count != otherIssues.Count)
return false;
for (int i = 0; i < issues.Count; i++)
{
if (!issues[i].Equals(otherIssues[i]))
{
return false;
}
}
var subreports = SubReports.ToList();
var otherSubreports = other.SubReports.ToList();
if (subreports.Count != otherSubreports.Count)
return false;
for (int i = 0; i < subreports.Count; i++)
{
if (!subreports[i].Equals(otherSubreports[i]))
{
return false;
}
}
return true;
}
public override string ToString()
{
return string.Format("{0}, severity: {1} ({2} error(s), {3} warning(s), {4} info)",
Category, Severity,
ErrorCount, WarningCount, InfoCount);
}
private static IList AsList(IEnumerable enumerable)
{
return enumerable as IList ?? enumerable.ToList();
}
}
}