using ZB.MOM.WW.Secrets.Abstractions;

namespace ZB.MOM.WW.Secrets.MasterKey;

/// <summary>
/// Selects and constructs the concrete <see cref="IMasterKeyProvider"/> matching a
/// <see cref="MasterKeyOptions.Source"/>.
/// </summary>
public static class MasterKeyProviderFactory
{
    /// <summary>
    /// Creates the master-key provider for the configured <see cref="MasterKeyOptions.Source"/>.
    /// </summary>
    /// <param name="options">The master-key configuration.</param>
    /// <returns>The matching provider.</returns>
    /// <exception cref="ArgumentNullException"><paramref name="options"/> is <see langword="null"/>.</exception>
    /// <exception cref="ArgumentOutOfRangeException">The configured source is not a known value.</exception>
    public static IMasterKeyProvider Create(MasterKeyOptions options)
    {
        ArgumentNullException.ThrowIfNull(options);

        return options.Source switch
        {
            MasterKeySource.Environment => new EnvironmentMasterKeyProvider(options),
            MasterKeySource.File => new FileMasterKeyProvider(options),
            // Constructing the DPAPI provider does no Windows-only work; the platform guard lives in
            // DpapiMasterKeyProvider.ResolveKeyBytes, which throws PlatformNotSupportedException off
            // Windows. Suppress the type-level CA1416 for this construction only.
#pragma warning disable CA1416
            MasterKeySource.Dpapi => new DpapiMasterKeyProvider(options),
#pragma warning restore CA1416
            _ => throw new ArgumentOutOfRangeException(
                nameof(options), options.Source, "Unknown master-key source."),
        };
    }
}
