using Microsoft.Extensions.Options;

namespace ZB.MOM.WW.LocalDb;

/// <summary>
/// Validates <see cref="LocalDbOptions"/> at startup, accumulating every failure into one result so
/// <c>ValidateOnStart</c> reports all problems at once. Mirrors the fail-closed rules the
/// <c>SqliteLocalDb</c> constructor also enforces.
/// </summary>
public sealed class LocalDbOptionsValidator : IValidateOptions<LocalDbOptions>
{
    // Interpolated into a PRAGMA statement by the host (pragmas cannot be parameterized), so it is
    // allow-listed. Shared with the SqliteLocalDb constructor so both enforce the identical set.
    internal static readonly string[] AllowedSynchronous = ["OFF", "NORMAL", "FULL", "EXTRA"];

    public ValidateOptionsResult Validate(string? name, LocalDbOptions options)
    {
        var failures = new List<string>();

        if (string.IsNullOrWhiteSpace(options.Path))
            failures.Add("LocalDb:Path is required.");

        if (options.BusyTimeoutMs <= 0)
            failures.Add($"LocalDb:BusyTimeoutMs must be greater than 0; got {options.BusyTimeoutMs}.");

        if (!Array.Exists(AllowedSynchronous,
                s => s.Equals(options.Synchronous, StringComparison.OrdinalIgnoreCase)))
            failures.Add(
                $"LocalDb:Synchronous must be one of {string.Join("/", AllowedSynchronous)}; got '{options.Synchronous}'.");

        return failures.Count > 0
            ? ValidateOptionsResult.Fail(failures)
            : ValidateOptionsResult.Success;
    }
}
