using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text.Json.Serialization; namespace Adaptation.FileHandlers.json.WorkItems; internal class Record { #nullable enable [JsonConstructor] public Record(WorkItem workItem, WorkItem? parent, Record[]? children, Record[]? related, Record[]? successors) { WorkItem = workItem; Parent = parent; Children = children; Related = related; Successors = successors; } [JsonPropertyName("WorkItem")] public WorkItem WorkItem { get; set; } [JsonPropertyName("Parent")] public WorkItem? Parent { get; set; } [JsonPropertyName("Children")] public Record[]? Children { get; set; } [JsonPropertyName("Related")] public Record[]? Related { get; set; } [JsonPropertyName("Successors")] public Record[]? Successors { get; set; } internal static Record GetWithoutNesting(Record record, string? violation) { Record result; WorkItem workItem = new(record.WorkItem.ActivatedDate, record.WorkItem.AreaPath, record.WorkItem.AssignedTo, record.WorkItem.BusinessValue, record.WorkItem.ChangedDate, record.WorkItem.ClosedDate, record.WorkItem.CommentCount, record.WorkItem.CreatedDate, record.WorkItem.Description, record.WorkItem.Effort, record.WorkItem.Id, record.WorkItem.IterationPath, record.WorkItem.Parent, record.WorkItem.Priority, record.WorkItem.Relations, record.WorkItem.Requester, record.WorkItem.ResolvedDate, record.WorkItem.Revision, record.WorkItem.RiskReductionMinusOpportunityEnablement, record.WorkItem.StartDate, record.WorkItem.State, record.WorkItem.Tags, record.WorkItem.TargetDate, record.WorkItem.TimeCriticality, record.WorkItem.Title, record.WorkItem.Violation is null ? violation : record.WorkItem.Violation, record.WorkItem.WeightedShortestJobFirst, record.WorkItem.WorkItemType); result = new(workItem, record.Parent, Array.Empty(), Array.Empty(), Array.Empty()); return result; } private static Record Get(Record record, bool keepRelations) { Record result; Record[]? childRecords; Record[]? relatedRecords; Record[]? successorRecords; List relationRecords; WorkItem? parentWorkItem = keepRelations ? record.Parent : WorkItem.GetWithOutRelations(record.Parent); WorkItem? workItem = keepRelations ? record.WorkItem : WorkItem.GetWithOutRelations(record.WorkItem) ?? throw new Exception(); if (record.Children is null) childRecords = null; else { relationRecords = new(); foreach (Record r in record.Children) relationRecords.Add(Get(r, keepRelations)); childRecords = relationRecords.ToArray(); } if (record.Related is null) relatedRecords = null; else { relationRecords = new(); foreach (Record r in record.Related) relationRecords.Add(Get(r, keepRelations)); relatedRecords = relationRecords.ToArray(); } if (record.Successors is null) successorRecords = null; else { relationRecords = new(); foreach (Record r in record.Successors) relationRecords.Add(Get(r, keepRelations)); successorRecords = relationRecords.ToArray(); } result = new(workItem, parentWorkItem, childRecords, relatedRecords, successorRecords); return result; } internal static Record Get(WorkItem workItem, WorkItem? parent, ReadOnlyCollection? children, ReadOnlyCollection? related, ReadOnlyCollection? successors, bool keepRelations) { Record result; Record record = new(workItem, parent, children?.ToArray(), related?.ToArray(), successors?.ToArray()); result = Get(record, keepRelations); return result; } internal static ReadOnlyCollection GetKeyValuePairs(ReadOnlyDictionary keyValuePairs, WorkItem workItem, string relationName, List nests, bool keepRelations) { List results = new(); Record record; nests.Add(true); WorkItem? parentWorkItem; WorkItem? relationWorkItem; List collection = new(); ReadOnlyCollection? childRecords; ReadOnlyCollection? relatedRecords; ReadOnlyCollection? successorRecords; if (workItem.Relations is not null && workItem.Relations.Length > 0) { collection.Clear(); foreach (Relation relation in workItem.Relations) { if (relation.Attributes.Name != relationName) continue; if (workItem.Parent is not null && relation.Id == workItem.Parent.Value) continue; if (!keyValuePairs.TryGetValue(relation.Id, out relationWorkItem)) continue; collection.Add(relationWorkItem); } collection = (from l in collection orderby l.State != "Closed", l.Id select l).ToList(); foreach (WorkItem w in collection) { if (nests.Count > 500) break; if (w.Parent is null) parentWorkItem = null; else _ = keyValuePairs.TryGetValue(w.Parent.Value, out parentWorkItem); childRecords = GetKeyValuePairs(keyValuePairs, w, "Child", nests, keepRelations); // Forward relatedRecords = null; // GetKeyValuePairs(keyValuePairs, w, "Related", nests, keepRelations); // Related successorRecords = null; // GetKeyValuePairs(keyValuePairs, w, "Successor", nests, keepRelations); // Forward // predecessorRecords = GetKeyValuePairs(keyValuePairs, w, "Predecessor", nests, keepRelations); // Reverse record = Get(w, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations); results.Add(record); } } return new(results); } } [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Record))] internal partial class RecordSourceGenerationContext : JsonSerializerContext { } [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Record[]))] internal partial class RecordCollectionSourceGenerationContext : JsonSerializerContext { }