using MeetingAssistant.MeetingNotes; using YamlDotNet.Serialization; namespace MeetingAssistant.Summary; internal static class MeetingSummaryFrontmatterFactory { private static readonly IDeserializer YamlDeserializer = new DeserializerBuilder() .IgnoreUnmatchedProperties() .Build(); public static async Task CreateAsync( MeetingSessionArtifacts artifacts, MeetingNote meetingNote, string title, CancellationToken cancellationToken) { var frontmatter = MeetingArtifactFrontmatterRenderer.Create( artifacts, meetingNote, title, artifacts.SummaryPath); frontmatter.Attendees = await ResolveSummaryAttendeesAsync( artifacts.SummaryPath, meetingNote, cancellationToken); frontmatter.Projects = CopyNonEmptyList(meetingNote.Frontmatter.Projects); return frontmatter; } private static async Task?> ResolveSummaryAttendeesAsync( string summaryPath, MeetingNote meetingNote, CancellationToken cancellationToken) { var existingAttendees = await ReadExistingSummaryAttendeesAsync(summaryPath, cancellationToken); return existingAttendees ?? CopyNonEmptyList(meetingNote.Frontmatter.Attendees); } private static List? CopyNonEmptyList(IReadOnlyCollection values) { return values.Count == 0 ? null : values.ToList(); } private static async Task?> ReadExistingSummaryAttendeesAsync( string summaryPath, CancellationToken cancellationToken) { if (!File.Exists(summaryPath)) { return null; } var content = await File.ReadAllTextAsync(summaryPath, cancellationToken); var document = MarkdownDocumentParser.SplitOptional(content); if (!document.HasFrontmatter) { return null; } var yaml = YamlDeserializer.Deserialize(document.Frontmatter); return yaml?.Attendees; } private sealed class SummaryFrontmatterYaml { [YamlMember(Alias = "attendees")] public List? Attendees { get; set; } } }