using Microsoft.Extensions.DependencyInjection; using StellaOps.AdvisoryAI.Remediation.ScmConnector; using StellaOps.Plugin.Abstractions; using StellaOps.Plugin.Abstractions.Capabilities; namespace StellaOps.AdvisoryAI.Scm.Plugin.Unified; /// /// Factory for creating unified SCM plugin adapters from existing connectors. /// public sealed class ScmPluginAdapterFactory { private readonly ScmConnectorCatalog _catalog; private readonly Dictionary _adapters = new(StringComparer.OrdinalIgnoreCase); private readonly object _lock = new(); /// /// Creates a new factory instance. /// /// The SCM connector catalog. public ScmPluginAdapterFactory(ScmConnectorCatalog catalog) { _catalog = catalog ?? throw new ArgumentNullException(nameof(catalog)); } /// /// Gets all available unified SCM plugins. /// /// Connector options. /// List of unified SCM plugins. public IReadOnlyList GetAllPlugins(ScmConnectorOptions options) { var result = new List(); foreach (var plugin in _catalog.Plugins) { if (plugin.IsAvailable(options)) { var adapter = GetOrCreateAdapter(plugin.ScmType, options); if (adapter != null) { result.Add(adapter); } } } return result; } /// /// Gets a unified SCM plugin by SCM type. /// /// SCM type identifier. /// Connector options. /// Unified SCM plugin, or null if not found. public IPlugin? GetPlugin(string scmType, ScmConnectorOptions options) { return GetOrCreateAdapter(scmType, options); } /// /// Gets a unified SCM plugin that can handle the given repository URL. /// /// Repository URL to handle. /// Connector options. /// Unified SCM plugin, or null if not found. public IPlugin? GetPluginForRepository(string repositoryUrl, ScmConnectorOptions options) { var plugin = _catalog.Plugins.FirstOrDefault(p => p.CanHandle(repositoryUrl)); if (plugin == null) return null; return GetOrCreateAdapter(plugin.ScmType, options); } /// /// Gets the SCM capability for a connector. /// /// SCM type identifier. /// Connector options. /// SCM capability, or null if not found. public IScmCapability? GetCapability(string scmType, ScmConnectorOptions options) { return GetOrCreateAdapter(scmType, options); } private ScmPluginAdapter? GetOrCreateAdapter(string scmType, ScmConnectorOptions options) { lock (_lock) { if (_adapters.TryGetValue(scmType, out var existing)) { return existing; } var plugin = _catalog.Plugins.FirstOrDefault( p => p.ScmType.Equals(scmType, StringComparison.OrdinalIgnoreCase)); if (plugin == null || !plugin.IsAvailable(options)) { return null; } var connector = _catalog.GetConnector(scmType, options); if (connector == null) { return null; } var adapter = new ScmPluginAdapter(connector, plugin, options); _adapters[scmType] = adapter; return adapter; } } } /// /// Extension methods for registering unified SCM plugin services. /// public static class ScmPluginAdapterExtensions { /// /// Adds unified SCM plugin adapter services to the service collection. /// /// Service collection. /// Service collection for chaining. public static IServiceCollection AddUnifiedScmPlugins(this IServiceCollection services) { services.AddSingleton(); return services; } }