file-exposer/Models/Review.cs
2025-05-10 13:31:06 -07:00

234 lines
8.9 KiB
C#

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<Record> records)
{
Review result;
ReadOnlyCollection<Segment> areEqual = GetAreEqual(relativePath, records);
ReadOnlyCollection<Segment> notEqualBut = GetNotEqualBut(relativePath, records);
ReadOnlyCollection<Segment> leftSideOnly = GetLeftSideOnly(relativePath, records);
ReadOnlyCollection<Segment> rightSideOnly = GetRightSideOnly(relativePath, records);
ReadOnlyCollection<Segment> leftSideIsNewer = GetLeftSideIsNewer(relativePath, records);
ReadOnlyCollection<Segment> 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<Segment> GetAreEqual(RelativePath relativePath, ReadOnlyCollection<Record> records)
{
List<Segment> results = [];
Record? record;
Segment segment;
double totalSeconds;
string? checkDirectory = null;
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(relativePath);
foreach (Record r in records)
{
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
{
checkDirectory = r.RelativePath;
continue;
}
if (r.RelativePath == relativePath.Path)
continue;
if (!keyValuePairs.TryGetValue(r.RelativePath, out 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,
LeftDirectory: checkDirectory,
Right: record,
RightDirectory: relativePath.Path);
results.Add(segment);
}
return results.AsReadOnly();
}
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(RelativePath relativePath) =>
GetKeyValuePairs(relativePath.Records.AsReadOnly());
private static ReadOnlyDictionary<string, Record> GetKeyValuePairs(ReadOnlyCollection<Record> records)
{
Dictionary<string, Record> results = [];
foreach (Record record in records)
results.Add(record.RelativePath, record);
return new(results);
}
private static ReadOnlyCollection<Segment> GetNotEqualBut(RelativePath relativePath, ReadOnlyCollection<Record> records)
{
List<Segment> results = [];
Record? record;
Segment segment;
double totalSeconds;
string? checkDirectory = null;
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(relativePath);
foreach (Record r in records)
{
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
{
checkDirectory = r.RelativePath;
continue;
}
if (r.RelativePath == relativePath.Path)
continue;
if (!keyValuePairs.TryGetValue(r.RelativePath, out 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,
LeftDirectory: checkDirectory,
Right: record,
RightDirectory: relativePath.Path);
results.Add(segment);
}
return results.AsReadOnly();
}
private static ReadOnlyCollection<Segment> GetLeftSideOnly(RelativePath relativePath, ReadOnlyCollection<Record> records)
{
List<Segment> results = [];
Record? record;
Segment segment;
string? checkDirectory = null;
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(relativePath);
foreach (Record r in records)
{
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
{
checkDirectory = r.RelativePath;
continue;
}
if (r.RelativePath == relativePath.Path)
continue;
if (keyValuePairs.TryGetValue(r.RelativePath, out record))
continue;
segment = new(Left: r,
LeftDirectory: checkDirectory,
Right: record,
RightDirectory: relativePath.Path);
results.Add(segment);
}
return results.AsReadOnly();
}
private static ReadOnlyCollection<Segment> GetRightSideOnly(RelativePath relativePath, ReadOnlyCollection<Record> records)
{
List<Segment> results = [];
Record? record;
Segment segment;
string? checkDirectory = null;
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(records);
foreach (Record r in relativePath.Records)
{
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
{
checkDirectory = r.RelativePath;
continue;
}
if (r.RelativePath == relativePath.Path)
continue;
if (keyValuePairs.TryGetValue(r.RelativePath, out record))
continue;
segment = new(Left: record,
LeftDirectory: null,
Right: r,
RightDirectory: relativePath.Path);
results.Add(segment);
}
return results.AsReadOnly();
}
private static ReadOnlyCollection<Segment> GetLeftSideIsNewer(RelativePath relativePath, ReadOnlyCollection<Record> records)
{
List<Segment> results = [];
Record? record;
Segment segment;
double totalSeconds;
string? checkDirectory = null;
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(relativePath);
foreach (Record r in records)
{
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
{
checkDirectory = r.RelativePath;
continue;
}
if (r.RelativePath == relativePath.Path)
continue;
if (!keyValuePairs.TryGetValue(r.RelativePath, out record))
continue;
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
if (totalSeconds is > -2)
continue;
segment = new(Left: r,
LeftDirectory: checkDirectory,
Right: record,
RightDirectory: relativePath.Path);
results.Add(segment);
}
return results.AsReadOnly();
}
private static ReadOnlyCollection<Segment> GetRightSideIsNewer(RelativePath relativePath, ReadOnlyCollection<Record> records)
{
List<Segment> results = [];
Record? record;
Segment segment;
double totalSeconds;
string? checkDirectory = null;
ReadOnlyDictionary<string, Record> keyValuePairs = GetKeyValuePairs(records);
foreach (Record r in relativePath.Records)
{
if (checkDirectory is null && r.Size == 0 && r.Ticks == 0)
{
checkDirectory = r.RelativePath;
continue;
}
if (r.RelativePath == relativePath.Path)
continue;
if (!keyValuePairs.TryGetValue(r.RelativePath, out record))
continue;
totalSeconds = new TimeSpan(record.Ticks - r.Ticks).TotalSeconds;
if (totalSeconds is > -2)
continue;
segment = new(Left: record,
LeftDirectory: null,
Right: r,
RightDirectory: relativePath.Path);
results.Add(segment);
}
return results.AsReadOnly();
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(Review))]
public partial class ReviewSourceGenerationContext : JsonSerializerContext
{
}