using Microsoft.Extensions.DependencyInjection;

namespace ZB.MOM.WW.ScadaBridge.DeploymentManager;

public static class ServiceCollectionExtensions
{
    /// <summary>
    /// Configuration section that <see cref="DeploymentManagerOptions"/> is bound to.
    /// The Host binds this section to <c>appsettings.json</c> (see
    /// <c>Program.cs</c>); component libraries do not depend on
    /// <c>IConfiguration</c> directly, consistent with the Options-pattern
    /// convention enforced by <c>OptionsTests</c>.
    /// </summary>
    public const string OptionsSection = "ScadaBridge:DeploymentManager";

    /// <summary>
    /// Registers the Deployment Manager services. <see cref="DeploymentManagerOptions"/>
    /// is registered via <see cref="OptionsServiceCollectionExtensions.AddOptions"/> so
    /// <c>IOptions&lt;DeploymentManagerOptions&gt;</c> is always resolvable; the Host
    /// binds <see cref="OptionsSection"/> to configuration so the operation-lock and
    /// artifact-deployment timeouts are tunable via <c>appsettings.json</c>.
    /// </summary>
    /// <param name="services">The service collection to register into.</param>
    /// <returns>The <paramref name="services"/> instance for chaining.</returns>
    public static IServiceCollection AddDeploymentManager(this IServiceCollection services)
    {
        // DeploymentManager-008: ensure the options class is always resolvable.
        // The Host binds OptionsSection to appsettings.json; absent that binding
        // the declared option-class defaults apply.
        services.AddOptions<DeploymentManagerOptions>();
        services.AddSingleton<OperationLockManager>();

        // CentralUI-006: push-based deployment-status notification. Registered
        // as a singleton so the scoped DeploymentService and the Central UI's
        // scoped Blazor page component share one instance — both run in the
        // same central Host process. The deployment-status page subscribes to
        // it instead of polling the database every 10 seconds.
        services.AddSingleton<IDeploymentStatusNotifier, DeploymentStatusNotifier>();

        services.AddScoped<IFlatteningPipeline, FlatteningPipeline>();
        services.AddScoped<DeploymentService>();
        services.AddScoped<ArtifactDeploymentService>();
        return services;
    }

    /// <summary>
    /// Registers Deployment Manager Akka actor bindings. Actor creation is handled by the Host during actor system startup.
    /// </summary>
    /// <param name="services">The service collection to register into.</param>
    /// <returns>The <paramref name="services"/> instance for chaining.</returns>
    public static IServiceCollection AddDeploymentManagerActors(this IServiceCollection services)
    {
        // Akka actor registration is handled by Host component during actor system startup
        return services;
    }
}
