using Microsoft.Extensions.Options;

namespace ZB.MOM.WW.Configuration;

/// <summary>
/// Base class for <see cref="IValidateOptions{TOptions}"/> implementations that removes the
/// failure-accumulation plumbing. Override <see cref="Validate(ValidationBuilder, TOptions)"/> and
/// use the supplied <see cref="ValidationBuilder"/>; the base aggregates ALL failures and returns
/// <see cref="ValidateOptionsResult.Success"/> only when none were recorded.
/// </summary>
/// <typeparam name="TOptions">The options type being validated.</typeparam>
public abstract class OptionsValidatorBase<TOptions> : IValidateOptions<TOptions>
    where TOptions : class
{
    /// <inheritdoc />
    public ValidateOptionsResult Validate(string? name, TOptions options)
    {
        ArgumentNullException.ThrowIfNull(options);
        var builder = new ValidationBuilder();
        Validate(builder, options);
        return builder.IsValid
            ? ValidateOptionsResult.Success
            : ValidateOptionsResult.Fail(builder.Failures);
    }

    /// <summary>Records validation failures for <paramref name="options"/> on <paramref name="builder"/>.</summary>
    /// <param name="builder">The accumulator to record failures on.</param>
    /// <param name="options">The options instance to validate.</param>
    protected abstract void Validate(ValidationBuilder builder, TOptions options);
}
