using System.Globalization; using Core.Entities; using CsvHelper; using CsvHelper.Configuration; using FuzzySharp; namespace Core.Parsers { public class TeamWriter { private readonly ICollection _teams; public string Filename { get; } public TeamWriter(ICollection teams, string filename) { _teams = teams; Filename = filename; } public void Write() { var csvConfiguration = new CsvConfiguration(CultureInfo.CurrentCulture) { HasHeaderRecord = true, }; using var writer = new StreamWriter(Filename); using var csv = new CsvWriter(writer, csvConfiguration); // header csv.WriteField("Team Name"); csv.WriteField("Event Name"); var max = _teams.Max(t => t.Students.Count); for (var i = 1; i < max + 1; i++) { csv.WriteField($"Student {i}"); } foreach (var team in _teams) { csv.WriteField(team.Identifier); csv.WriteField(team.Event.Name); foreach (var teamStudent in team.Students) { csv.WriteField(teamStudent.Name); } csv.NextRecord(); } } } public class TeamParser : CsvParserBase { public TeamParser(FileSystemInfo csvFile, bool ignoreBlankLines = true) : base(csvFile, ignoreBlankLines) { } public Team[] Parse(ICollection events, ICollection students) { var teams = new List(); CsvReader.Read(); CsvReader.ReadHeader(); while (CsvReader.Read()) { var eventName = CsvReader.GetField("Event Name"); if (string.IsNullOrEmpty(eventName)) continue; if (eventName.StartsWith("Team Size")) continue; eventName = eventName.Replace("ᵃ", string.Empty); eventName = eventName.Replace("ⁱ", string.Empty); eventName = eventName.TrimEnd(); var teamName = CsvReader.GetField("Team Name"); if (string.IsNullOrEmpty(teamName)) teamName = eventName; eventName = eventName.Trim(); var @event = (from e in events let rat = Fuzz.Ratio(e.Name, eventName) where rat > 50 orderby rat descending select e).FirstOrDefault(); if (@event == null) continue; var regionalTimeSlot = CsvReader.GetField("Regional Time Slot"); if (!string.IsNullOrEmpty(regionalTimeSlot)) regionalTimeSlot.Trim(); var teamStudents = new List(); Student? captain = null; for (var i = 1; i <= 9; i++) { var studentName = CsvReader.GetField($"Student {i}"); if (string.IsNullOrEmpty(studentName)) continue; studentName = studentName.Trim(); if (studentName == "?") continue; var studentMatches = from s in students let rat = new[] { Fuzz.Ratio(s.Name, studentName), Fuzz.Ratio(s.FirstNameLastName, studentName), Fuzz.Ratio(s.FirstName, studentName) }.Max() where rat > 90 orderby rat descending select s; var student = studentMatches.FirstOrDefault(); if (student == null) { //continue; throw new ArgumentException($"Student named '{studentName}' not found"); } teamStudents.Add(student); if (i == 1) captain = student; } var teamNumber = string.Empty; if (teamName.EndsWith("Team 2")) teamNumber = "12227-2"; else if (@event.EventFormat == EventFormat.Team) teamNumber = "2227"; if (teamStudents.Count > 0) { if (@event.EventFormat is EventFormat.Team) { teams.Add(new Team { Event = @event, Students = teamStudents, Captain = captain, Identifier = teamNumber}); } else if (@event.EventFormat is EventFormat.Individual) { foreach (var student in teamStudents) { teams.Add(new Team{Event = @event, Students = [student], Captain = student, Identifier = teamNumber}); } } } } return teams.ToArray(); } } }