using NATS.Server.Configuration;

namespace NATS.Server.Core.Tests;

// Go reference: server/signal_unix.go (handleSignals), server/reload.go (Reload)

public class SignalHandlerTests
{
    [Fact]
    public void SignalHandler_registers_without_throwing()
    {
        // Go reference: server/signal_unix.go — registration should succeed
        Should.NotThrow(() => SignalHandler.Register(() => { }));
        SignalHandler.IsRegistered.ShouldBeTrue();
        SignalHandler.Unregister();
        SignalHandler.IsRegistered.ShouldBeFalse();
    }

    [Fact]
    public async Task ConfigReloader_ReloadFromOptionsAsync_applies_reloadable_changes()
    {
        // Go reference: server/reload.go — reloadable options (e.g., MaxPayload) pass validation
        var original = new NatsOptions { Port = 4222, MaxPayload = 1024 };
        var updated = new NatsOptions { Port = 4222, MaxPayload = 2048 }; // MaxPayload is reloadable

        var result = await ConfigReloader.ReloadFromOptionsAsync(original, updated);
        result.Success.ShouldBeTrue();
        result.RejectedChanges.ShouldBeEmpty();
    }

    [Fact]
    public async Task ConfigReloader_rejects_non_reloadable_changes()
    {
        // Go reference: server/reload.go — Port change is NOT reloadable
        var original = new NatsOptions { Port = 4222 };
        var updated = new NatsOptions { Port = 5555 }; // port change is NOT reloadable

        var result = await ConfigReloader.ReloadFromOptionsAsync(original, updated);
        result.RejectedChanges.ShouldContain(c => c.Contains("Port"));
    }

    [Fact]
    public async Task ConfigReloader_identical_options_succeeds()
    {
        // Go reference: server/reload.go — no changes = success
        var original = new NatsOptions { Port = 4222 };
        var updated = new NatsOptions { Port = 4222 };

        var result = await ConfigReloader.ReloadFromOptionsAsync(original, updated);
        result.Success.ShouldBeTrue();
        result.RejectedChanges.ShouldBeEmpty();
    }

    [Fact]
    public void SignalHandler_unregister_is_idempotent()
    {
        // Calling Unregister when not registered should not throw
        Should.NotThrow(() => SignalHandler.Unregister());
        Should.NotThrow(() => SignalHandler.Unregister());
    }
}
