using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Questionable.Model; using Questionable.Model.Questing; namespace Questionable.Validation; internal sealed class QuestValidator { private readonly IReadOnlyList _validators; private readonly ILogger _logger; private List _validationIssues = new List(); public IReadOnlyList Issues => _validationIssues; public int IssueCount => _validationIssues.Count; public int ErrorCount => _validationIssues.Count((ValidationIssue x) => x.Severity == EIssueSeverity.Error); public QuestValidator(IEnumerable validators, ILogger logger) { _validators = validators.ToList(); _logger = logger; _logger.LogInformation("Validators: {Validators}", string.Join(", ", _validators.Select((IQuestValidator x) => x.GetType().Name))); } public void Reset() { foreach (IQuestValidator validator in _validators) { validator.Reset(); } _validationIssues.Clear(); } public void Validate(IEnumerable quests) { Task.Factory.StartNew(delegate { try { _validationIssues.Clear(); List list = new List(); Dictionary dictionary = new Dictionary(); foreach (Quest quest in quests) { foreach (IQuestValidator validator in _validators) { foreach (ValidationIssue item in validator.Validate(quest)) { if (item.Type == EIssueType.QuestDisabled && quest.Info.AlliedSociety != EAlliedSociety.None) { dictionary.TryAdd(quest.Info.AlliedSociety, 0); dictionary[quest.Info.AlliedSociety]++; } else { list.Add(item); } } } } List disabledQuests = (from x in list where x.Type == EIssueType.QuestDisabled select x.ElementId).ToList(); _validationIssues = (from x in list where !disabledQuests.Contains(x.ElementId) || x.Type == EIssueType.QuestDisabled orderby x.ElementId, x.Sequence, x.Step, x.Description select x).Concat(DisabledTribesAsIssues(dictionary)).ToList(); } catch (Exception exception) { _logger.LogError(exception, "Unable to validate quests"); } }, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); } public List GetIssues(ElementId elementId) { return _validationIssues.Where((ValidationIssue x) => x.ElementId == elementId).ToList(); } private static IEnumerable DisabledTribesAsIssues(Dictionary disabledTribeQuests) { return from x in disabledTribeQuests orderby x.Key select new ValidationIssue { ElementId = null, Sequence = null, Step = null, AlliedSociety = x.Key, Type = EIssueType.QuestDisabled, Severity = EIssueSeverity.None, Description = $"{x.Value} disabled quest(s)" }; } }