using Core.Entities; using Core.Models; using System.Text.Json; namespace Core.Validation; /// /// Configuration for validation thresholds and rules /// public class ValidationConfiguration { // Event count thresholds /// /// Minimum recommended number of events per student (Warning if below) /// public int MinRecommendedEvents { get; set; } = 2; /// /// Maximum recommended number of events per student (Warning if above) /// public int MaxRecommendedEvents { get; set; } = 4; /// /// Minimum critical number of events per student (Error if below) /// public int MinCriticalEvents { get; set; } = 1; /// /// Maximum critical number of events per student (Error if above) /// public int MaxCriticalEvents { get; set; } = 6; /// /// Maximum recommended number of regional events per student (Warning if above) /// public int MaxRegionalEvents { get; set; } = 3; // Required event types /// /// Whether to require students to have at least one regional event /// public bool RequireRegionalEvent { get; set; } = true; /// /// Whether to require students to have at least one on-site activity /// public bool RequireOnSiteActivity { get; set; } = true; /// /// Whether to require students to have at least one individual event /// public bool RequireIndividualEvent { get; set; } = false; /// /// Whether to require team-based events to have an assigned captain /// public bool RequireTeamCaptain { get; set; } = true; // Severity levels for each rule type /// /// Severity level for "No Regional Event" warnings /// public ValidationSeverity NoRegionalEventSeverity { get; set; } = ValidationSeverity.Warning; /// /// Severity level for "No On-Site Activity" warnings /// public ValidationSeverity NoOnSiteActivitySeverity { get; set; } = ValidationSeverity.Warning; /// /// Severity level for "No Individual Event" warnings /// public ValidationSeverity NoIndividualEventSeverity { get; set; } = ValidationSeverity.Warning; /// /// Severity level for team size warnings /// public ValidationSeverity TeamSizeSeverity { get; set; } = ValidationSeverity.Warning; /// /// Severity level for event count warnings /// public ValidationSeverity EventCountSeverity { get; set; } = ValidationSeverity.Warning; /// /// Severity level for missing captain warnings /// public ValidationSeverity MissingCaptainSeverity { get; set; } = ValidationSeverity.Warning; /// /// Severity level for too many regional events warnings /// public ValidationSeverity TooManyRegionalEventsSeverity { get; set; } = ValidationSeverity.Warning; /// /// Default configuration matching current app behavior /// public static ValidationConfiguration Default => new() { RequireRegionalEvent = true, RequireOnSiteActivity = true, RequireIndividualEvent = false, MinRecommendedEvents = 2, MaxRecommendedEvents = 4, MinCriticalEvents = 1, MaxCriticalEvents = 6, MaxRegionalEvents = 3, RequireTeamCaptain = true, NoRegionalEventSeverity = ValidationSeverity.Warning, NoOnSiteActivitySeverity = ValidationSeverity.Warning, NoIndividualEventSeverity = ValidationSeverity.Warning, TeamSizeSeverity = ValidationSeverity.Warning, EventCountSeverity = ValidationSeverity.Warning, MissingCaptainSeverity = ValidationSeverity.Warning, TooManyRegionalEventsSeverity = ValidationSeverity.Warning }; /// /// Create validation configuration from assignment parameters /// /// Assignment parameters to convert /// Validation configuration matching the assignment parameters public static ValidationConfiguration FromAssignmentParameters(AssignmentParameters parameters) { return new ValidationConfiguration { RequireRegionalEvent = parameters.RequireRegional, RequireOnSiteActivity = parameters.RequireOnSite, MinRecommendedEvents = parameters.EventsLowerBound, MaxRecommendedEvents = parameters.EventsUpperBound, MinCriticalEvents = 1, MaxCriticalEvents = 6, RequireTeamCaptain = true, NoRegionalEventSeverity = ValidationSeverity.Warning, NoOnSiteActivitySeverity = ValidationSeverity.Warning, NoIndividualEventSeverity = ValidationSeverity.Warning, TeamSizeSeverity = ValidationSeverity.Warning, EventCountSeverity = ValidationSeverity.Warning, MissingCaptainSeverity = ValidationSeverity.Warning }; } /// /// Deserialize validation configuration from JSON string /// /// JSON string containing configuration /// ValidationConfiguration instance or Default if deserialization fails public static ValidationConfiguration FromJson(string json) { try { var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() } }; return JsonSerializer.Deserialize(json, options) ?? Default; } catch { return Default; } } /// /// Load validation configuration from a JSON file /// /// Path to the JSON configuration file /// ValidationConfiguration instance or Default if file doesn't exist or loading fails public static async Task LoadFromFileAsync(string path) { try { if (!File.Exists(path)) return Default; var json = await File.ReadAllTextAsync(path); return FromJson(json); } catch { return Default; } } /// /// Save this validation configuration to a JSON file /// /// Path where the JSON file should be saved public async Task SaveToFileAsync(string path) { var options = new JsonSerializerOptions { WriteIndented = true, Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() } }; var json = JsonSerializer.Serialize(this, options); await File.WriteAllTextAsync(path, json); } }