using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Text.Json.Serialization; namespace FileExposer.Models; public record Review(Segment[]? AreEqual, Segment[]? LeftSideIsNewer, Segment[]? LeftSideOnly, Segment[]? NotEqualBut, Record[]? Records, Segment[]? RightSideIsNewer, Segment[]? RightSideOnly) { internal static Review Get(RelativePath relativePath, ReadOnlyCollection records) { Review result; ReadOnlyCollection areEqual = GetAreEqual(relativePath, records); ReadOnlyCollection notEqualBut = GetNotEqualBut(relativePath, records); ReadOnlyCollection leftSideOnly = GetLeftSideOnly(relativePath, records); ReadOnlyCollection rightSideOnly = GetRightSideOnly(relativePath, records); ReadOnlyCollection leftSideIsNewer = GetLeftSideIsNewer(relativePath, records); ReadOnlyCollection rightSideIsNewer = GetRightSideIsNewer(relativePath, records); result = new(AreEqual: [.. areEqual], LeftSideIsNewer: [.. leftSideIsNewer], LeftSideOnly: [.. leftSideOnly], NotEqualBut: [.. notEqualBut], Records: null, RightSideIsNewer: [.. rightSideIsNewer], RightSideOnly: [.. rightSideOnly]); return result; } private static ReadOnlyCollection GetAreEqual(RelativePath relativePath, ReadOnlyCollection records) { List results = []; Segment segment; double totalSeconds; ReadOnlyDictionary keyValuePairs = GetKeyValuePairs(relativePath); foreach (Record r in records) { if (!keyValuePairs.TryGetValue(r.RelativePath, out Record? record)) continue; totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds; if (record.Size != r.Size || totalSeconds is > 2 or < -2) continue; segment = new(Left: r, Right: record); results.Add(segment); } return results.AsReadOnly(); } private static ReadOnlyDictionary GetKeyValuePairs(RelativePath relativePath) => GetKeyValuePairs(relativePath.Records.AsReadOnly()); private static ReadOnlyDictionary GetKeyValuePairs(ReadOnlyCollection records) { Dictionary results = []; foreach (Record record in records) results.Add(record.RelativePath, record); return new(results); } private static ReadOnlyCollection GetNotEqualBut(RelativePath relativePath, ReadOnlyCollection records) { List results = []; Segment segment; double totalSeconds; ReadOnlyDictionary keyValuePairs = GetKeyValuePairs(relativePath); foreach (Record r in records) { if (!keyValuePairs.TryGetValue(r.RelativePath, out Record? record)) continue; if (record.Size == r.Size) continue; totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds; if (totalSeconds is >= 2 or <= -2) continue; segment = new(Left: r, Right: record); results.Add(segment); } return results.AsReadOnly(); } private static ReadOnlyCollection GetLeftSideOnly(RelativePath relativePath, ReadOnlyCollection records) { List results = []; Segment segment; ReadOnlyDictionary keyValuePairs = GetKeyValuePairs(relativePath); foreach (Record r in records) { if (keyValuePairs.TryGetValue(r.RelativePath, out Record? record)) continue; segment = new(Left: r, Right: record); results.Add(segment); } return results.AsReadOnly(); } private static ReadOnlyCollection GetRightSideOnly(RelativePath relativePath, ReadOnlyCollection records) { List results = []; Segment segment; ReadOnlyDictionary keyValuePairs = GetKeyValuePairs(records); foreach (Record r in relativePath.Records) { if (keyValuePairs.TryGetValue(r.RelativePath, out Record? record)) continue; segment = new(Left: record, Right: r); results.Add(segment); } return results.AsReadOnly(); } private static ReadOnlyCollection GetLeftSideIsNewer(RelativePath relativePath, ReadOnlyCollection records) { List results = []; Segment segment; double totalSeconds; ReadOnlyDictionary keyValuePairs = GetKeyValuePairs(relativePath); foreach (Record r in records) { if (!keyValuePairs.TryGetValue(r.RelativePath, out Record? record)) continue; totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds; if (totalSeconds is > -2) continue; segment = new(Left: r, Right: record); results.Add(segment); } return results.AsReadOnly(); } private static ReadOnlyCollection GetRightSideIsNewer(RelativePath relativePath, ReadOnlyCollection records) { List results = []; Segment segment; double totalSeconds; ReadOnlyDictionary keyValuePairs = GetKeyValuePairs(records); foreach (Record r in relativePath.Records) { if (!keyValuePairs.TryGetValue(r.RelativePath, out Record? record)) continue; totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds; if (totalSeconds is > -2) continue; segment = new(Left: record, Right: r); results.Add(segment); } return results.AsReadOnly(); } } [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Review))] public partial class ReviewSourceGenerationContext : JsonSerializerContext { }