using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IOB_MAN.Core
{
///
/// Classe TaskRunStats gestisce le statistiche di esecuzione dei task.
/// Memorizza e calcola i tempi medi, il numero di esecuzioni e le dimensioni dei dati.
/// Supporta il salvataggio delle statistiche su disco e il caricamento da file esistenti.
///
public class TaskRunStats
{
#region Public Constructors
///
/// Inizializza una nuova istanza della classe con dati vuoti.
/// Utilizzato quando non è necessario caricare dati da file.
///
public TaskRunStats()
{
// Inizializzazione generica senza rilettura dei dati dal disco
}
///
/// Inizializza una nuova istanza della classe con rilettura dei dati dal disco.
/// Carica eventuali statistiche memorizzate in un file di configurazione.
///
/// Directory dell'applicazione dove si trova il file di configurazione.
/// Nome del file di configurazione da cui caricare i dati.
public TaskRunStats(string appDir, string confName)
{
AppDir = appDir;
ConfName = confName;
// Inizia il caricamento dei dati dal disco (se presenti)
tryReload();
}
#endregion Public Constructors
#region Public Properties
///
/// Tempo medio complessivo registrato per tutti i task.
/// Calcolato sommando i tempi medi di ogni singolo task.
///
public TimeSpan AvgTotalTime
{
get
{
TimeSpan answ = new TimeSpan();
if (TaskData != null && TaskData.Count > 0)
{
foreach (var record in TaskData)
{
answ += record.Value.AvgTime;
}
}
return answ;
}
}
///
/// Numero totale di statistiche memorizzate per i task.
/// Rappresenta il conteggio dei record presenti nel dizionario.
///
public int NumItems
{
get
{
return TaskData.Count;
}
}
///
/// Dimensione massima delle statistiche memorizzate per un task.
/// Indica il numero massimo di esecuzioni registrate per un singolo task.
///
public long SampleSizeMax
{
get
{
return TaskData.Max(x => x.Value.NumRun);
}
}
///
/// Dizionario che contiene le statistiche per ogni task registrato.
/// Ogni chiave rappresenta il nome del task, ogni valore contiene le informazioni di esecuzione.
///
public Dictionary TaskData { get; set; } = new Dictionary();
#endregion Public Properties
#region Public Methods
///
/// Calcola il tempo medio per un task specifico.
///
/// Nome del task per cui si desidera calcolare il tempo medio.
/// Tempo medio per il task specificato.
public TimeSpan AvgTaskTime(string taskName)
{
TimeSpan answ = new TimeSpan();
if (TaskData != null && TaskData.Count > 0)
{
if (TaskData.ContainsKey(taskName))
{
answ = TaskData[taskName].AvgTime;
}
}
return answ;
}
///
/// Resetta tutte le statistiche e le azzera.
///
public void ForceReset()
{
TaskData = new Dictionary();
}
///
/// Registra i dati di un'operazione di esecuzione per un task specifico.
/// Aggiorna i dati esistenti o crea un nuovo record se il task non è già presente.
///
/// Nome del task che viene eseguito.
/// Durata dell'esecuzione in unità di tempo.
public void RecordExeData(string taskName, TimeSpan duration)
{
// Cerca nel dizionario se il task è già presente
if (TaskData.ContainsKey(taskName))
{
TaskData[taskName].NumRun++;
TaskData[taskName].TotalTime += duration;
}
else
{
TaskData.Add(taskName, new TaskStat() { NumRun = 1, TotalTime = duration });
}
}
///
/// Salva le statistiche memorizzate sul disco in un file JSON.
///
public void SaveToDisk()
{
var rawData = JsonConvert.SerializeObject(TaskData, Formatting.Indented);
if (rawData != null && rawData.Length > 2)
{
File.WriteAllText(StatsPath, rawData);
}
}
#endregion Public Methods
#region Private Fields
///
/// Oggetto logger per il rilevamento degli eventi e degli errori.
///
private static Logger Log = LogManager.GetCurrentClassLogger();
#endregion Private Fields
#region Private Properties
///
/// Directory dell'applicazione dove si trova il file di configurazione.
///
private string AppDir { get; set; } = "";
///
/// Nome del file di configurazione da cui caricare i dati.
///
private string ConfName { get; set; } = "";
///
/// Percorso del file di statistiche su disco.
/// Generato dinamicamente con Path.Combine(AppDir, ConfName).
///
private string StatsPath
{
get => Path.Combine(AppDir, ConfName);
}
#endregion Private Properties
#region Private Methods
///
/// Tenta il caricamento dei dati dal file di configurazione.
/// Se il file esiste, lo legge e lo deserializza in un dizionario.
/// Gestisce eventuali eccezioni di deserializzazione.
///
private void tryReload()
{
if (File.Exists(StatsPath))
{
string rawData = File.ReadAllText(StatsPath);
if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2)
{
try
{
TaskData = JsonConvert.DeserializeObject>(rawData) ?? new Dictionary();
}
catch (Exception exc)
{
Log.Error($"Eccezione in tryReload:{Environment.NewLine}{exc}");
}
}
}
}
#endregion Private Methods
}
}