using System.Globalization; namespace StellaOps.Bench.ScannerAnalyzers.Baseline; internal static class BaselineLoader { public static async Task> LoadAsync(string path, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentException("Baseline path must be provided.", nameof(path)); } var resolved = Path.GetFullPath(path); if (!File.Exists(resolved)) { throw new FileNotFoundException($"Baseline file not found at {resolved}", resolved); } var result = new Dictionary(StringComparer.OrdinalIgnoreCase); await using var stream = new FileStream(resolved, FileMode.Open, FileAccess.Read, FileShare.Read); using var reader = new StreamReader(stream); string? line; var isFirst = true; while ((line = await reader.ReadLineAsync().ConfigureAwait(false)) is not null) { cancellationToken.ThrowIfCancellationRequested(); if (string.IsNullOrWhiteSpace(line)) { continue; } if (isFirst) { isFirst = false; if (line.StartsWith("scenario,", StringComparison.OrdinalIgnoreCase)) { continue; } } var entry = ParseLine(line); result[entry.ScenarioId] = entry; } return result; } private static BaselineEntry ParseLine(string line) { var parts = line.Split(',', StringSplitOptions.TrimEntries); if (parts.Length < 6) { throw new InvalidDataException($"Baseline CSV row malformed: '{line}'"); } var scenarioId = parts[0]; var iterations = ParseInt(parts[1], nameof(BaselineEntry.Iterations)); var sampleCount = ParseInt(parts[2], nameof(BaselineEntry.SampleCount)); var meanMs = ParseDouble(parts[3], nameof(BaselineEntry.MeanMs)); var p95Ms = ParseDouble(parts[4], nameof(BaselineEntry.P95Ms)); var maxMs = ParseDouble(parts[5], nameof(BaselineEntry.MaxMs)); return new BaselineEntry(scenarioId, iterations, sampleCount, meanMs, p95Ms, maxMs); } private static int ParseInt(string value, string field) { if (!int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsed)) { throw new InvalidDataException($"Failed to parse integer {field} from '{value}'."); } return parsed; } private static double ParseDouble(string value, string field) { if (!double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed)) { throw new InvalidDataException($"Failed to parse double {field} from '{value}'."); } return parsed; } }