using System;
using System.Linq;

namespace StellaOps.Configuration;

/// <summary>
/// Helper utilities for bootstrapping StellaOps Authority configuration.
/// </summary>
public static class StellaOpsAuthorityConfiguration
{
    private static readonly string[] DefaultAuthorityYamlFiles =
    {
        "authority.yaml",
        "authority.local.yaml",
        "etc/authority.yaml",
        "etc/authority.local.yaml"
    };

    /// <summary>
    /// Builds <see cref="StellaOpsAuthorityOptions"/> using the shared configuration bootstrapper.
    /// </summary>
    /// <param name="configure">Optional hook to customise bootstrap behaviour.</param>
    public static StellaOpsConfigurationContext<StellaOpsAuthorityOptions> Build(
        Action<StellaOpsBootstrapOptions<StellaOpsAuthorityOptions>>? configure = null)
    {
        return StellaOpsConfigurationBootstrapper.Build<StellaOpsAuthorityOptions>(options =>
        {
            options.BindingSection ??= "Authority";
            options.EnvironmentPrefix ??= "STELLAOPS_AUTHORITY_";

            configure?.Invoke(options);

            AppendDefaultYamlFiles(options);

            var previousPostBind = options.PostBind;
            options.PostBind = (authorityOptions, configuration) =>
            {
                previousPostBind?.Invoke(authorityOptions, configuration);
                authorityOptions.Validate();
            };
        });
    }

    private static void AppendDefaultYamlFiles(StellaOpsBootstrapOptions<StellaOpsAuthorityOptions> options)
    {
        foreach (var path in DefaultAuthorityYamlFiles)
        {
            var alreadyPresent = options.YamlFiles.Any(file =>
                string.Equals(file.Path, path, StringComparison.OrdinalIgnoreCase));

            if (!alreadyPresent)
            {
                options.YamlFiles.Add(new YamlConfigurationFile(path, Optional: true));
            }
        }
    }
}
