using Microsoft.Extensions.Options;

namespace ZB.MOM.WW.ScadaBridge.ManagementService.Tests;

/// <summary>
/// Arch-review 08 §1.5: <see cref="ManagementServiceOptions"/> supplies the Ask timeouts
/// the ManagementActor client uses for command and long-running transport/deploy calls. A
/// zero/negative timeout makes every command fail (or Ask forever); reject it fast at startup
/// with a key-naming message. <see cref="ManagementServiceOptions.SecuredWritePendingTtl"/> is
/// deliberately NOT required positive — a non-positive value legitimately disables server-side
/// secured-write expiry.
/// </summary>
public class ManagementServiceOptionsValidatorTests
{
    private static ValidateOptionsResult Validate(ManagementServiceOptions options) =>
        new ManagementServiceOptionsValidator().Validate(Options.DefaultName, options);

    [Fact]
    public void DefaultOptions_AreValid()
    {
        var result = Validate(new ManagementServiceOptions());
        Assert.True(result.Succeeded, result.FailureMessage);
    }

    [Fact]
    public void NonPositiveSecuredWritePendingTtl_IsValid()
    {
        // A non-positive TTL disables server-side expiry by design — not a config error.
        var result = Validate(new ManagementServiceOptions { SecuredWritePendingTtl = TimeSpan.Zero });
        Assert.True(result.Succeeded, result.FailureMessage);
    }

    [Fact]
    public void ZeroCommandTimeout_IsRejected()
    {
        var result = Validate(new ManagementServiceOptions { CommandTimeout = TimeSpan.Zero });

        Assert.True(result.Failed);
        Assert.Contains("CommandTimeout", result.FailureMessage);
    }

    [Fact]
    public void NegativeCommandTimeout_IsRejected()
    {
        var result = Validate(new ManagementServiceOptions { CommandTimeout = TimeSpan.FromSeconds(-1) });

        Assert.True(result.Failed);
        Assert.Contains("CommandTimeout", result.FailureMessage);
    }

    [Fact]
    public void ZeroLongRunningCommandTimeout_IsRejected()
    {
        var result = Validate(new ManagementServiceOptions { LongRunningCommandTimeout = TimeSpan.Zero });

        Assert.True(result.Failed);
        Assert.Contains("LongRunningCommandTimeout", result.FailureMessage);
    }
}
