using Adaptation.Shared; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; namespace Adaptation.FileHandlers.pcl; #nullable enable internal class Run { public Run(Header header, Summary summary, ReadOnlyCollection points) { Header = header; Summary = summary; Points = points; } public Header Header { get; } public Summary Summary { get; } public ReadOnlyCollection Points { get; } private static ReadOnlyCollection FilterLines(ReadOnlyCollection collection) { List results = new(); foreach (string line in collection) { if (string.IsNullOrEmpty(line) || line is "*" or "@") continue; if (line.Length < 3 || line[0] is not '*' and not '@' || line[1] != ' ') results.Add(line); else results.Add(line.Substring(2)); } return new(results); } private static void WriteJson(Logistics logistics, List fileInfoCollection, Run? result) { FileInfo fileInfo = new($"{logistics.ReportFullPath}.json"); string json = JsonSerializer.Serialize(result, RunSourceGenerationContext.Default.Run); File.WriteAllText(fileInfo.FullName, json); File.SetLastWriteTime(fileInfo.FullName, logistics.DateTimeFromSequence); fileInfoCollection.Add(fileInfo); } private static ReadOnlyCollection GetLines(JsonElement[]? jsonElements) { List results = new(); int columns = 0; StringBuilder stringBuilder = new(); for (int i = 0; i < jsonElements?.Length;) { foreach (JsonProperty jsonProperty in jsonElements[0].EnumerateObject()) { columns += 1; _ = stringBuilder.Append('"').Append(jsonProperty.Name).Append('"').Append('\t'); } break; } if (jsonElements?.Length != 0) _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); results.Add(stringBuilder.ToString()); for (int i = 0; i < jsonElements?.Length; i++) { _ = stringBuilder.Clear(); foreach (JsonProperty jsonProperty in jsonElements[i].EnumerateObject()) { if (jsonProperty.Value.ValueKind == JsonValueKind.Object) _ = stringBuilder.Append('\t'); else if (jsonProperty.Value.ValueKind != JsonValueKind.String) _ = stringBuilder.Append(jsonProperty.Value).Append('\t'); else _ = stringBuilder.Append('"').Append(jsonProperty.Value).Append('"').Append('\t'); } _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); results.Add(stringBuilder.ToString()); } return results.AsReadOnly(); } private static ReadOnlyCollection GetLines(JsonElement jsonElement) => GetLines(new JsonElement[] { jsonElement }); private static void WriteTabSeparatedValues(Logistics logistics, List fileInfoCollection, Run run) { List results = new(); Row row; FileInfo fileInfo = new($"{logistics.ReportFullPath}.tsv"); for (int i = 0; i < run.Points.Count; i++) { row = new(run, i); results.Add(row); } string json = JsonSerializer.Serialize(results); JsonElement[]? jsonElements = JsonSerializer.Deserialize(json); ReadOnlyCollection lines = GetLines(jsonElements); File.WriteAllText(fileInfo.FullName, string.Join(Environment.NewLine, lines)); File.SetLastWriteTime(fileInfo.FullName, logistics.DateTimeFromSequence); fileInfoCollection.Add(fileInfo); } private static void WriteException(Logistics logistics, Exception ex) { FileInfo fileInfo = new($"{logistics.ReportFullPath}.{nameof(Exception)}.txt"); File.WriteAllText(fileInfo.FullName, $"{ex.Message}{Environment.NewLine}{ex.StackTrace}"); } public static Run? Get(Logistics logistics, List fileInfoCollection, ReadOnlyCollection collection) { Run? result; Constant constant = new(); ReadOnlyCollection lines = FilterLines(collection); if (collection.Count <= constant.Take) result = null; else { Header? header = Header.Get(constant, lines); if (header is null) result = null; else { Summary? summary = SummarySegment.Get(constant, lines); if (summary is null) result = null; else { ReadOnlyCollection points = Point.GetCollection(constant, lines) ?? throw new NullReferenceException(nameof(summary)); if (points.Count == 0) result = null; else { result = new(header, summary, points); WriteJson(logistics, fileInfoCollection, result); try { WriteTabSeparatedValues(logistics, fileInfoCollection, result); } catch (Exception ex) { WriteException(logistics, ex); } } } } } return result; } } [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(Run))] internal partial class RunSourceGenerationContext : JsonSerializerContext { }