using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using StellaOps.VexLens.Api;
using StellaOps.VexLens.Caching;
using StellaOps.VexLens.Consensus;
using StellaOps.VexLens.Export;
using StellaOps.VexLens.Integration;
using StellaOps.VexLens.Orchestration;
using StellaOps.VexLens.Mapping;
using StellaOps.VexLens.Normalization;
using StellaOps.VexLens.Observability;
using StellaOps.VexLens.Options;
using StellaOps.VexLens.Storage;
using StellaOps.VexLens.Trust;
using StellaOps.VexLens.Trust.SourceTrust;
using StellaOps.VexLens.Verification;
namespace StellaOps.VexLens.Extensions;
///
/// Extension methods for registering VexLens services.
///
public static class VexLensServiceCollectionExtensions
{
///
/// Adds VexLens consensus engine services to the service collection.
///
public static IServiceCollection AddVexLens(
this IServiceCollection services,
IConfiguration configuration)
{
var section = configuration.GetSection(VexLensOptions.SectionName);
services.Configure(section);
var options = section.Get() ?? new VexLensOptions();
return services.AddVexLensCore(options);
}
///
/// Adds VexLens consensus engine services with explicit options.
///
public static IServiceCollection AddVexLens(
this IServiceCollection services,
Action configure)
{
var options = new VexLensOptions();
configure(options);
services.Configure(configure);
return services.AddVexLensCore(options);
}
///
/// Adds VexLens services for testing with in-memory storage.
///
public static IServiceCollection AddVexLensForTesting(this IServiceCollection services)
{
var options = new VexLensOptions
{
Storage = { Driver = "memory" },
Telemetry = { MetricsEnabled = false, TracingEnabled = false }
};
return services.AddVexLensCore(options);
}
private static IServiceCollection AddVexLensCore(
this IServiceCollection services,
VexLensOptions options)
{
// Normalization
services.TryAddSingleton(sp =>
{
var registry = new VexNormalizerRegistry();
RegisterNormalizers(registry, options.Normalization);
return registry;
});
// Product mapping
services.TryAddSingleton();
// Verification
services.TryAddSingleton();
// Issuer directory - use in-memory by default, can be replaced
services.TryAddSingleton();
// Trust engine (statement-level)
services.TryAddSingleton();
// Source trust scoring (source-level)
services.TryAddSingleton(Microsoft.Extensions.Options.Options.Create(
SourceTrustScoreConfiguration.CreateDefault()));
services.TryAddSingleton();
services.TryAddSingleton();
services.TryAddSingleton();
services.TryAddSingleton();
services.TryAddSingleton();
services.TryAddSingleton();
services.TryAddSingleton();
services.TryAddSingleton();
services.TryAddSingleton();
// Consensus engine
services.TryAddSingleton();
// Storage
RegisterStorage(services, options.Storage);
// Event emitter - in-memory for now
services.TryAddSingleton();
// API service
services.TryAddScoped();
// Rationale service for AI/ML consumption
services.TryAddScoped();
// Rationale cache for Advisory AI
services.TryAddSingleton();
// Integration services
services.TryAddScoped();
services.TryAddScoped();
// Export service for offline bundles
services.TryAddScoped();
// Orchestrator job service for scheduling consensus compute
services.TryAddScoped();
// Metrics
if (options.Telemetry.MetricsEnabled)
{
services.TryAddSingleton();
}
return services;
}
private static void RegisterNormalizers(
VexNormalizerRegistry registry,
VexLensNormalizationOptions options)
{
var enabledFormats = new HashSet(
options.EnabledFormats,
StringComparer.OrdinalIgnoreCase);
if (enabledFormats.Contains("OpenVEX"))
{
registry.Register(new OpenVexNormalizer());
}
if (enabledFormats.Contains("CSAF"))
{
registry.Register(new CsafVexNormalizer());
}
if (enabledFormats.Contains("CycloneDX"))
{
registry.Register(new CycloneDxVexNormalizer());
}
}
private static void RegisterStorage(
IServiceCollection services,
VexLensStorageOptions options)
{
var driver = (options.Driver ?? "memory").Trim();
switch (driver.ToLowerInvariant())
{
case "memory":
services.TryAddSingleton(sp =>
{
var emitter = sp.GetRequiredService();
return new InMemoryConsensusProjectionStore(emitter);
});
break;
default:
throw new InvalidOperationException(
$"Unsupported VexLens storage driver: '{options.Driver}'. Supported drivers: memory.");
}
}
}