222 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			222 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Collections.ObjectModel;
 | |
| using System.IO;
 | |
| using System.Linq;
 | |
| using System.Text.Json;
 | |
| using System.Text.Json.Serialization;
 | |
| 
 | |
| namespace Adaptation.FileHandlers.Priority;
 | |
| 
 | |
| #nullable enable
 | |
| 
 | |
| public class Aggregation
 | |
| {
 | |
| 
 | |
|     [JsonConstructor]
 | |
|     public Aggregation(double inverseAverage,
 | |
|                        int valueCount,
 | |
|                        double fibonacciAverage,
 | |
|                        int? inverseValue,
 | |
|                        int valueMaximum,
 | |
|                        int valueMinimum,
 | |
|                        Notification[] notifications,
 | |
|                        int valueSum)
 | |
|     {
 | |
|         InverseAverage = inverseAverage;
 | |
|         ValueCount = valueCount;
 | |
|         FibonacciAverage = fibonacciAverage;
 | |
|         InverseValue = inverseValue;
 | |
|         ValueMaximum = valueMaximum;
 | |
|         ValueMinimum = valueMinimum;
 | |
|         Notifications = notifications;
 | |
|         ValueSum = valueSum;
 | |
|     }
 | |
| 
 | |
|     public double InverseAverage { get; } // [JsonPropertyName("InverseAverage")]
 | |
|     public int ValueCount { get; } // [JsonPropertyName("ValueCount")]
 | |
|     public double FibonacciAverage { get; } // [JsonPropertyName("Fibonacci")]
 | |
|     public int? InverseValue { get; } // [JsonPropertyName("InverseValue")]
 | |
|     public int ValueMaximum { get; } // [JsonPropertyName("ValueMaximum")]
 | |
|     public int ValueMinimum { get; } // [JsonPropertyName("ValueMinimum")]
 | |
|     public Notification[] Notifications { get; } // [JsonPropertyName("Notifications")]
 | |
|     public int ValueSum { get; } // [JsonPropertyName("ValueSum")]
 | |
| 
 | |
|     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Dictionary<int, List<Notification>> keyValuePairs)
 | |
|     {
 | |
|         Dictionary<int, Aggregation> results = new();
 | |
|         int value;
 | |
|         int? inverseValue;
 | |
|         double inverseAverage;
 | |
|         Aggregation aggregation;
 | |
|         double fibonacciAverage;
 | |
|         List<int> collection = new();
 | |
|         int averageFromInverseCeiling;
 | |
|         List<int> inverseCollection = new();
 | |
|         List<int> fibonacciCollection = new();
 | |
|         foreach (KeyValuePair<int, List<Notification>> keyValuePair in keyValuePairs)
 | |
|         {
 | |
|             collection.Clear();
 | |
|             inverseCollection.Clear();
 | |
|             fibonacciCollection.Clear();
 | |
|             foreach (Notification notification in keyValuePair.Value)
 | |
|             {
 | |
|                 if (!int.TryParse(notification.Value, out value))
 | |
|                     continue;
 | |
|                 collection.Add(value);
 | |
|                 if (notification.Inverse is null)
 | |
|                     continue;
 | |
|                 inverseCollection.Add(notification.Inverse.Value);
 | |
|                 if (notification.Fibonacci is null)
 | |
|                     continue;
 | |
|                 fibonacciCollection.Add(notification.Fibonacci.Value);
 | |
|             }
 | |
|             if (inverseCollection.Count == 0 || fibonacciCollection.Count == 0)
 | |
|                 continue;
 | |
|             inverseAverage = Math.Round(inverseCollection.Average(), settings.Digits);
 | |
|             averageFromInverseCeiling = (int)Math.Ceiling(inverseAverage);
 | |
|             inverseValue = Notification.GetInverse(averageFromInverseCeiling.ToString());
 | |
|             fibonacciAverage = Math.Round(fibonacciCollection.Average(), settings.Digits);
 | |
|             aggregation = new(inverseAverage: inverseAverage,
 | |
|                               valueCount: collection.Count,
 | |
|                               fibonacciAverage: fibonacciAverage,
 | |
|                               inverseValue: inverseValue,
 | |
|                               valueMaximum: collection.Max(),
 | |
|                               valueMinimum: collection.Min(),
 | |
|                               notifications: keyValuePair.Value.ToArray(),
 | |
|                               valueSum: collection.Sum());
 | |
|             results.Add(keyValuePair.Key, aggregation);
 | |
|         }
 | |
|         return new(results);
 | |
|     }
 | |
| 
 | |
|     private static ReadOnlyCollection<Notification> GetNotifications(Settings settings, string directory)
 | |
|     {
 | |
|         List<Notification> results = new();
 | |
|         string? key;
 | |
|         string text;
 | |
|         string[] files;
 | |
|         Notification? notification;
 | |
|         List<Notification>? collection;
 | |
|         Dictionary<string, List<Notification>> keyValuePairs = new();
 | |
|         string[] directories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
 | |
|         foreach (string subDirectory in directories)
 | |
|         {
 | |
|             keyValuePairs.Clear();
 | |
|             files = Directory.GetFiles(subDirectory, settings.SourceFileFilter, SearchOption.TopDirectoryOnly);
 | |
|             foreach (string file in files)
 | |
|             {
 | |
|                 text = File.ReadAllText(file);
 | |
|                 if (string.IsNullOrEmpty(text) || text[0] == '[')
 | |
|                     continue;
 | |
|                 notification = JsonSerializer.Deserialize(text, NotificationSourceGenerationContext.Default.Notification);
 | |
|                 if (notification is null || string.IsNullOrEmpty(notification.Id))
 | |
|                     continue;
 | |
|                 key = !string.IsNullOrEmpty(notification.Username) ? notification.Username : throw new Exception();
 | |
|                 if (string.IsNullOrEmpty(key))
 | |
|                     continue;
 | |
|                 if (!keyValuePairs.TryGetValue(key, out collection))
 | |
|                 {
 | |
|                     keyValuePairs.Add(key, new());
 | |
|                     if (!keyValuePairs.TryGetValue(key, out collection))
 | |
|                         throw new Exception();
 | |
|                 }
 | |
|                 collection.Add(notification);
 | |
|             }
 | |
|             foreach (KeyValuePair<string, List<Notification>> keyValuePair in keyValuePairs)
 | |
|             {
 | |
|                 if (keyValuePair.Value.Count == 1)
 | |
|                     results.Add(keyValuePair.Value[0]);
 | |
|                 else
 | |
|                 {
 | |
|                     notification = keyValuePair.Value.Select(record => new KeyValuePair<string, Notification>(record.Time, record)).OrderBy(pair => pair.Key).Last().Value;
 | |
|                     results.Add(notification);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         return new(results);
 | |
|     }
 | |
| 
 | |
|     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, string directory)
 | |
|     {
 | |
|         ReadOnlyDictionary<int, Aggregation> results;
 | |
|         int id;
 | |
|         List<Notification>? collection;
 | |
|         Dictionary<int, List<Notification>> keyValuePairs = new();
 | |
|         ReadOnlyCollection<Notification> notifications = GetNotifications(settings, directory);
 | |
|         foreach (Notification notification in notifications)
 | |
|         {
 | |
|             if (!int.TryParse(notification.Id, out id))
 | |
|                 continue;
 | |
|             if (!keyValuePairs.TryGetValue(id, out collection))
 | |
|             {
 | |
|                 keyValuePairs.Add(id, new());
 | |
|                 if (!keyValuePairs.TryGetValue(id, out collection))
 | |
|                     throw new Exception();
 | |
|             }
 | |
|             collection.Add(notification);
 | |
|         }
 | |
|         results = GetKeyValuePairs(settings, keyValuePairs);
 | |
|         return results;
 | |
|     }
 | |
| 
 | |
|     internal static ReadOnlyDictionary<string, ReadOnlyDictionary<int, Aggregation>> GetKeyValuePairsAndWriteFiles(Settings settings)
 | |
|     {
 | |
|         Dictionary<string, ReadOnlyDictionary<int, Aggregation>> results = new();
 | |
|         string json;
 | |
|         string jsonOld;
 | |
|         string jsonFile;
 | |
|         string directoryName;
 | |
|         ReadOnlyDictionary<int, Aggregation> keyValuePairs;
 | |
|         if (!Directory.Exists(settings.SourceFileLocation))
 | |
|             _ = Directory.CreateDirectory(settings.SourceFileLocation);
 | |
|         if (!Directory.Exists(settings.TargetFileLocation))
 | |
|             _ = Directory.CreateDirectory(settings.TargetFileLocation);
 | |
|         string[] directories = Directory.GetDirectories(settings.SourceFileLocation, "*", SearchOption.TopDirectoryOnly);
 | |
|         foreach (string directory in directories)
 | |
|         {
 | |
|             directoryName = Path.GetFileName(directory);
 | |
|             keyValuePairs = GetKeyValuePairs(settings, directory);
 | |
|             jsonFile = Path.Combine(settings.TargetFileLocation, $"{directoryName}.json");
 | |
|             json = JsonSerializer.Serialize(keyValuePairs, AggregationReadOnlyDictionarySourceGenerationContext.Default.ReadOnlyDictionaryInt32Aggregation);
 | |
|             // keyValuePairs = JsonSerializer.Deserialize(json, AggregationReadOnlyDictionarySourceGenerationContext.Default.ReadOnlyDictionaryInt32Aggregation);
 | |
|             jsonOld = File.Exists(jsonFile) ? File.ReadAllText(jsonFile) : string.Empty;
 | |
|             if (json != jsonOld)
 | |
|                 File.WriteAllText(jsonFile, json);
 | |
|             results.Add(directoryName, keyValuePairs);
 | |
|         }
 | |
|         return new(results);
 | |
|     }
 | |
| 
 | |
|     internal static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Notification notification)
 | |
|     {
 | |
|         ReadOnlyDictionary<int, Aggregation> results;
 | |
|         if (string.IsNullOrEmpty(notification.Id) || !int.TryParse(notification.Id, out int id))
 | |
|             results = new(new Dictionary<int, Aggregation>());
 | |
|         else
 | |
|         {
 | |
|             Dictionary<int, List<Notification>> keyValuePairs = new() { { id, new Notification[] { notification }.ToList() } };
 | |
|             results = GetKeyValuePairs(settings, keyValuePairs);
 | |
|         }
 | |
|         return results;
 | |
|     }
 | |
| 
 | |
| }
 | |
| 
 | |
| [JsonSourceGenerationOptions(WriteIndented = true)]
 | |
| [JsonSerializable(typeof(Aggregation))]
 | |
| internal partial class AggregationSourceGenerationContext : JsonSerializerContext
 | |
| {
 | |
| }
 | |
| 
 | |
| [JsonSourceGenerationOptions(WriteIndented = true)]
 | |
| [JsonSerializable(typeof(Aggregation[]))]
 | |
| internal partial class AggregationCollectionSourceGenerationContext : JsonSerializerContext
 | |
| {
 | |
| }
 | |
| 
 | |
| [JsonSourceGenerationOptions(WriteIndented = true)]
 | |
| [JsonSerializable(typeof(ReadOnlyDictionary<int, Aggregation>))]
 | |
| internal partial class AggregationReadOnlyDictionarySourceGenerationContext : JsonSerializerContext
 | |
| {
 | |
| } |