using Ludarium.Domain; namespace Ludarium.Application; public sealed class SnapshotComparer : ISnapshotComparer { public IReadOnlyList Compare(IntegritySnapshot before, IntegritySnapshot after) { var changes = new List(); var beforeByArtifact = before.Items.ToDictionary(x => x.ArtifactId); var afterByArtifact = after.Items.ToDictionary(x => x.ArtifactId); foreach (var oldItem in before.Items) { if (afterByArtifact.TryGetValue(oldItem.ArtifactId, out var current)) { if (!oldItem.Sha256.Equals(current.Sha256, StringComparison.OrdinalIgnoreCase)) changes.Add(new(SnapshotChangeKind.ContentChanged, oldItem, current, "The artifact identity is retained but its verified SHA-256 changed.")); else if (!oldItem.RelativePath.Equals(current.RelativePath, StringComparison.OrdinalIgnoreCase) || oldItem.LibraryId != current.LibraryId) changes.Add(new(SnapshotChangeKind.Moved, oldItem, current, "Verified content retained its artifact identity at a new location.")); else changes.Add(new(SnapshotChangeKind.Unchanged, oldItem, current, "Path and verified content are unchanged.")); } else changes.Add(new(SnapshotChangeKind.Removed, oldItem, null, "The artifact is absent from the later available-root snapshot.")); } foreach (var current in after.Items.Where(x => !beforeByArtifact.ContainsKey(x.ArtifactId))) changes.Add(new(SnapshotChangeKind.Added, null, current, "A new artifact appears in the later snapshot.")); return changes.OrderBy(x => x.Kind).ThenBy(x => x.After?.RelativePath ?? x.Before?.RelativePath, StringComparer.OrdinalIgnoreCase).ToArray(); } }