using System.Globalization; namespace LehrerApp.WebUntis; public static class WebUntisClassRegisterEventReportParser { public static IReadOnlyList Parse(string content) { var rows = TabSeparatedTextReader.ParseRows(content, '\t'); if (rows.Count == 0) return []; var headers = rows[0] .Select((header, index) => (index == 0 ? header.TrimStart('\uFEFF') : header).Trim()) .ToArray(); var result = new List(); foreach (var row in rows.Skip(1)) { if (row.All(string.IsNullOrWhiteSpace)) continue; var values = new Dictionary(StringComparer.Ordinal); for (var index = 0; index < headers.Length; index++) values[headers[index]] = index < row.Count ? row[index].Trim() : null; result.Add(new UntisClassRegisterEventReportEntry( Get(values, "Klasse")?.Trim() ?? "", GermanShortDate(Get(values, "Datum")) ?? throw new InvalidDataException( "Ungültiges Datum in Spalte \"Datum\"."), Optional(Get(values, "Fach")), Get(values, "Name")?.Trim() ?? "", Optional(Get(values, "Benutzer")), Optional(Get(values, "Eintragskategorie")), Optional(Get(values, "Kategoriegruppe")), Optional(Get(values, "Text")))); } return result; } private static string? Get(IReadOnlyDictionary values, string key) => values.TryGetValue(key, out var value) ? value : null; private static string? Optional(string? value) => string.IsNullOrWhiteSpace(value) ? null : value.Trim(); private static int? GermanShortDate(string? value) { if (!DateOnly.TryParseExact(value?.Trim(), "dd.MM.yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out var date)) return null; return date.Year * 10_000 + date.Month * 100 + date.Day; } }