using NATS.Server.Configuration;

namespace NATS.Server.Core.Tests;

public class ConfigIntegrationTests
{
    [Fact]
    public void Server_WithConfigFile_LoadsOptionsFromFile()
    {
        var dir = Path.Combine(Path.GetTempPath(), $"nats_test_{Guid.NewGuid():N}");
        Directory.CreateDirectory(dir);
        try
        {
            var confPath = Path.Combine(dir, "test.conf");
            File.WriteAllText(confPath, "port: 14222\nmax_payload: 2mb\ndebug: true");

            var opts = ConfigProcessor.ProcessConfigFile(confPath);
            opts.Port.ShouldBe(14222);
            opts.MaxPayload.ShouldBe(2 * 1024 * 1024);
            opts.Debug.ShouldBeTrue();
        }
        finally
        {
            Directory.Delete(dir, true);
        }
    }

    [Fact]
    public void Server_CliOverridesConfig()
    {
        var dir = Path.Combine(Path.GetTempPath(), $"nats_test_{Guid.NewGuid():N}");
        Directory.CreateDirectory(dir);
        try
        {
            var confPath = Path.Combine(dir, "test.conf");
            File.WriteAllText(confPath, "port: 14222\ndebug: true");

            var opts = ConfigProcessor.ProcessConfigFile(confPath);
            opts.Port.ShouldBe(14222);

            // Simulate CLI override: user passed -p 5222 on command line
            var cliSnapshot = new NatsOptions { Port = 5222 };
            var cliFlags = new HashSet<string> { "Port" };
            ConfigReloader.MergeCliOverrides(opts, cliSnapshot, cliFlags);

            opts.Port.ShouldBe(5222);
            opts.Debug.ShouldBeTrue(); // Config file value preserved
        }
        finally
        {
            Directory.Delete(dir, true);
        }
    }

    [Fact]
    public void Reload_ChangingPort_ReturnsError()
    {
        var oldOpts = new NatsOptions { Port = 4222 };
        var newOpts = new NatsOptions { Port = 5222 };
        var changes = ConfigReloader.Diff(oldOpts, newOpts);
        var errors = ConfigReloader.Validate(changes);
        errors.Count.ShouldBeGreaterThan(0);
        errors[0].ShouldContain("Port");
    }

    [Fact]
    public void Reload_ChangingDebug_IsValid()
    {
        var oldOpts = new NatsOptions { Debug = false };
        var newOpts = new NatsOptions { Debug = true };
        var changes = ConfigReloader.Diff(oldOpts, newOpts);
        var errors = ConfigReloader.Validate(changes);
        errors.ShouldBeEmpty();
        changes.ShouldContain(c => c.IsLoggingChange);
    }
}
