using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Windows.Threading; namespace NetDocsForLLM.Services { public enum LogLevel { Error = 0, Warning = 1, Info = 2, Debug = 3 } /// /// Clase estática para logs que no depende de inyección de dependencias /// public static class AppLogger { private static readonly List _logEntries = new List(); private static int _errorCount = 0; private static int _warningCount = 0; private static int _typeCount = 0; private static int _memberCount = 0; private static string _logFilePath; private static StreamWriter _fileWriter; // Evento que se dispara cuando hay nuevos mensajes public static event EventHandler LogUpdated; static AppLogger() { // Configurar archivo de log string tempFolder = Path.Combine(Path.GetTempPath(), "NetDocsForLLM_" + DateTime.Now.ToString("yyyyMMdd_HHmmss")); Directory.CreateDirectory(tempFolder); _logFilePath = Path.Combine(tempFolder, "app_log.txt"); _fileWriter = new StreamWriter(_logFilePath, true) { AutoFlush = true }; LogInfo($"Log inicializado en: {_logFilePath}"); } public static void LogDebug(string message) { AddLogEntry(LogLevel.Debug, message); } public static void LogInfo(string message) { AddLogEntry(LogLevel.Info, message); } public static void LogWarning(string message) { _warningCount++; AddLogEntry(LogLevel.Warning, message); } public static void LogError(string message) { _errorCount++; AddLogEntry(LogLevel.Error, message); } public static void LogException(Exception ex) { _errorCount++; StringBuilder sb = new StringBuilder(); sb.AppendLine($"Excepción: {ex.Message}"); if (ex.StackTrace != null) { sb.AppendLine("Stack Trace:"); sb.AppendLine(ex.StackTrace); } if (ex.InnerException != null) { sb.AppendLine($"Inner Exception: {ex.InnerException.Message}"); } AddLogEntry(LogLevel.Error, sb.ToString()); } public static int ErrorCount => _errorCount; public static int WarningCount => _warningCount; public static int TypeCount => _typeCount; public static int MemberCount => _memberCount; public static void IncrementTypeCount() { _typeCount++; NotifyLogUpdated(); } public static void IncrementMemberCount() { _memberCount++; NotifyLogUpdated(); } private static void AddLogEntry(LogLevel level, string message) { var entry = new LogEntry { Timestamp = DateTime.Now, Level = level, Message = message }; _logEntries.Add(entry); // Escribir al archivo de log string levelText = GetLevelText(level); string logMessage = $"[{entry.Timestamp:yyyy-MM-dd HH:mm:ss}] [{levelText}] {message}"; _fileWriter.WriteLine(logMessage); // Notificar a los escuchadores NotifyLogUpdated(); } private static void NotifyLogUpdated() { // Invocar el evento en el hilo de la UI si está disponible LogUpdated?.Invoke(null, EventArgs.Empty); } public static string GetContent(LogLevel maxLevel = LogLevel.Debug) { StringBuilder sb = new StringBuilder(); foreach (var entry in _logEntries) { if (entry.Level <= maxLevel) { string levelText = GetLevelText(entry.Level); sb.AppendLine($"[{entry.Timestamp:yyyy-MM-dd HH:mm:ss}] [{levelText}] {entry.Message}"); } } return sb.ToString(); } private static string GetLevelText(LogLevel level) { switch (level) { case LogLevel.Error: return "ERROR"; case LogLevel.Warning: return "WARN"; case LogLevel.Info: return "INFO"; case LogLevel.Debug: return "DEBUG"; default: return level.ToString(); } } public static void Clear() { _logEntries.Clear(); _errorCount = 0; _warningCount = 0; // No reiniciar los contadores de tipos y miembros // ya que representan el progreso del análisis NotifyLogUpdated(); } private class LogEntry { public DateTime Timestamp { get; set; } public LogLevel Level { get; set; } public string Message { get; set; } } } }