using System; using System.Collections.Generic; using System.IO; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using StellaOps.Authority.Plugins.Abstractions; using StellaOps.Configuration; namespace StellaOps.Cli.Services; /// /// Emits Authority configuration diagnostics discovered during CLI startup. /// internal static class AuthorityDiagnosticsReporter { public static void Emit(IConfiguration configuration, ILogger logger) { ArgumentNullException.ThrowIfNull(configuration); ArgumentNullException.ThrowIfNull(logger); var basePath = Directory.GetCurrentDirectory(); EmitInternal(configuration, logger, basePath); } internal static void Emit(IConfiguration configuration, ILogger logger, string basePath) { ArgumentNullException.ThrowIfNull(configuration); ArgumentNullException.ThrowIfNull(logger); ArgumentNullException.ThrowIfNull(basePath); EmitInternal(configuration, logger, basePath); } private static void EmitInternal(IConfiguration configuration, ILogger logger, string basePath) { if (string.IsNullOrWhiteSpace(basePath)) { basePath = Directory.GetCurrentDirectory(); } var authoritySection = configuration.GetSection("Authority"); if (!authoritySection.Exists()) { return; } var authorityOptions = new StellaOpsAuthorityOptions(); authoritySection.Bind(authorityOptions); if (authorityOptions.Plugins.Descriptors.Count == 0) { return; } var resolvedBasePath = Path.GetFullPath(basePath); IReadOnlyList contexts; try { contexts = AuthorityPluginConfigurationLoader.Load(authorityOptions, resolvedBasePath); } catch (Exception ex) { logger.LogDebug(ex, "Failed to load Authority plug-in configuration for diagnostics."); return; } if (contexts.Count == 0) { return; } IReadOnlyList diagnostics; try { diagnostics = AuthorityPluginConfigurationAnalyzer.Analyze(contexts); } catch (Exception ex) { logger.LogDebug(ex, "Failed to analyze Authority plug-in configuration for diagnostics."); return; } if (diagnostics.Count == 0) { return; } var contextLookup = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var context in contexts) { if (context?.Manifest?.Name is { Length: > 0 } name && !contextLookup.ContainsKey(name)) { contextLookup[name] = context; } } foreach (var diagnostic in diagnostics) { var level = diagnostic.Severity switch { AuthorityConfigurationDiagnosticSeverity.Error => LogLevel.Error, AuthorityConfigurationDiagnosticSeverity.Warning => LogLevel.Warning, _ => LogLevel.Information }; if (!logger.IsEnabled(level)) { continue; } if (contextLookup.TryGetValue(diagnostic.PluginName, out var context) && context?.Manifest?.ConfigPath is { Length: > 0 } configPath) { logger.Log(level, "{DiagnosticMessage} (config: {ConfigPath})", diagnostic.Message, configPath); } else { logger.Log(level, "{DiagnosticMessage}", diagnostic.Message); } } } }