| 1 | using System.Text.Json; |
| 2 | |
| 3 | namespace CascadeIDE.Services; |
| 4 | |
| 5 | internal static class KbBaseKnowledgeListMerger |
| 6 | { |
| 7 | private static readonly JsonSerializerOptions IndentedJson = new() { WriteIndented = true }; |
| 8 | |
| 9 | private sealed record ListedFile(string Path, long SizeBytes, string ModifiedUtc); |
| 10 | |
| 11 | internal static string Merge(string overlayListJson, string embeddedListJson, string mergedSearchHint) |
| 12 | { |
| 13 | var overlayFiles = ParseFiles(overlayListJson); |
| 14 | var embeddedFiles = ParseFiles(embeddedListJson); |
| 15 | |
| 16 | var byPath = new Dictionary<string, ListedFile>(StringComparer.OrdinalIgnoreCase); |
| 17 | foreach (var f in overlayFiles) |
| 18 | byPath[f.Path] = f; |
| 19 | foreach (var f in embeddedFiles) |
| 20 | { |
| 21 | if (!byPath.ContainsKey(f.Path)) |
| 22 | byPath[f.Path] = f; |
| 23 | } |
| 24 | |
| 25 | var ordered = byPath.Values |
| 26 | .OrderBy(x => x.Path, StringComparer.Ordinal) |
| 27 | .Select(x => new { path = x.Path, size_bytes = x.SizeBytes, modified_utc = x.ModifiedUtc }) |
| 28 | .ToArray(); |
| 29 | |
| 30 | return JsonSerializer.Serialize(new { path = mergedSearchHint, files = ordered, total = ordered.Length }, IndentedJson); |
| 31 | } |
| 32 | |
| 33 | private static ListedFile[] ParseFiles(string json) |
| 34 | { |
| 35 | if (string.IsNullOrWhiteSpace(json)) |
| 36 | return []; |
| 37 | |
| 38 | JsonDocument doc; |
| 39 | try |
| 40 | { |
| 41 | doc = JsonDocument.Parse(json); |
| 42 | } |
| 43 | catch |
| 44 | { |
| 45 | return []; |
| 46 | } |
| 47 | |
| 48 | using (doc) |
| 49 | { |
| 50 | var root = doc.RootElement; |
| 51 | if (!root.TryGetProperty("files", out var filesEl) || filesEl.ValueKind != JsonValueKind.Array) |
| 52 | return []; |
| 53 | |
| 54 | var list = new List<ListedFile>(); |
| 55 | foreach (var el in filesEl.EnumerateArray()) |
| 56 | { |
| 57 | if (el.TryGetProperty("path", out var pathEl)) |
| 58 | { |
| 59 | var path = pathEl.ValueKind == JsonValueKind.String ? (pathEl.GetString() ?? "").Trim() : ""; |
| 60 | if (path.Length > 0) |
| 61 | { |
| 62 | var size = 0L; |
| 63 | if (el.TryGetProperty("size_bytes", out var sb) && sb.ValueKind == JsonValueKind.Number && |
| 64 | sb.TryGetInt64(out var sl)) |
| 65 | size = sl; |
| 66 | var mod = |
| 67 | el.TryGetProperty("modified_utc", out var m) && m.ValueKind == JsonValueKind.String |
| 68 | ? (m.GetString() ?? "") |
| 69 | : ""; |
| 70 | list.Add(new ListedFile(path, size, mod)); |
| 71 | } |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | return list.ToArray(); |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | |