using UnrealDemoScanner.Web.Models; namespace UnrealDemoScanner.Web.Services; public sealed class DetectionParser { public ScanOutputSummary Parse(string output, string jobId) { var findings = new List(); var lines = output.Replace("\r\n", "\n").Split('\n'); var now = DateTime.UtcNow; var detectedCount = 0; var warningCount = 0; var infoCount = 0; for (var i = 0; i < lines.Length; i++) { var line = lines[i].Trim(); if (line.Length == 0) { continue; } string? kind = null; if (ContainsToken(line, "[DETECTED]") || ContainsToken(line, "[ОБНАРУЖЕНО]")) { kind = "detected"; detectedCount++; } else if (ContainsToken(line, "[WARNING]") || ContainsToken(line, "[ПРЕДУПРЕЖДЕНИЕ]")) { kind = "warning"; warningCount++; } else if (ContainsToken(line, "[INFO]") || ContainsToken(line, "[ИНФОРМАЦИЯ]") || ContainsToken(line, "[PLUGIN]")) { kind = "info"; infoCount++; } if (kind is null) { continue; } findings.Add(new ScanFinding { JobId = jobId, Kind = kind, LineNumber = i + 1, Message = line, CreatedAtUtc = now }); } return new ScanOutputSummary { Findings = findings, DetectedCount = detectedCount, WarningCount = warningCount, InfoCount = infoCount }; } private static bool ContainsToken(string line, string token) { return line.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0; } }