namespace Azaion.Missions.Infrastructure; public static class ConfigurationResolver { // Fail-fast contract: missing or whitespace-only values throw at startup so a // production deploy without the operator-confirmed values cannot silently // accept an insecure default (e.g. a development JWT secret, a localhost DB). public static string ResolveRequiredOrThrow( IConfiguration configuration, string envVar, string configKey, string humanLabel) { ArgumentNullException.ThrowIfNull(configuration); var value = Environment.GetEnvironmentVariable(envVar); if (string.IsNullOrWhiteSpace(value)) value = configuration[configKey]; if (string.IsNullOrWhiteSpace(value)) throw new InvalidOperationException( $"{humanLabel} is not configured. Set the {envVar} environment variable " + $"or the {configKey} configuration key."); return value; } // Optional positive-integer override (e.g. JWKS refresh interval tuning for tests). // Returns null when unset/whitespace so callers keep library defaults. // Throws when set-but-unparseable or non-positive, so a typo can never silently // weaken behavior. public static int? ResolveOptionalPositiveIntOrThrow( IConfiguration configuration, string envVar, string configKey, string humanLabel) { ArgumentNullException.ThrowIfNull(configuration); var raw = Environment.GetEnvironmentVariable(envVar); if (string.IsNullOrWhiteSpace(raw)) raw = configuration[configKey]; if (string.IsNullOrWhiteSpace(raw)) return null; if (!int.TryParse(raw, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out var parsed) || parsed <= 0) { throw new InvalidOperationException( $"{humanLabel} is set to '{raw}' which is not a positive integer. " + $"Set {envVar} (or {configKey}) to a positive integer count of seconds, or unset it to use the library default."); } return parsed; } }