// Port of Go server/reload_test.go — extended config reload parity tests.
// Covers: no-config-file reload, unsupported option changes, invalid config,
// auth rotation, token auth, multiple users, max payload, max control line,
// ping interval, max pings out, write deadline, max pending, debug/trace toggles,
// authorization timeout, client advertise, PID file changes, log file rotation,
// connect error reports, max subscriptions, cluster config changes, and more.
// Reference: golang/nats-server/server/reload_test.go

using System.Net;
using System.Net.Sockets;
using System.Text;
using Microsoft.Extensions.Logging.Abstractions;
using NATS.Client.Core;
using NATS.Server.Configuration;
using NATS.Server.TestUtilities;

namespace NATS.Server.Core.Tests.Configuration;

/// <summary>
/// Extended parity tests for config hot reload behaviour ported from Go's
/// reload_test.go. Each test writes a config file, starts the server,
/// changes the config, triggers a reload, and verifies the change took effect.
/// </summary>
public class ConfigReloadExtendedParityTests
{
    // ─── Helpers ────────────────────────────────────────────────────────────

    private static async Task<Socket> RawConnectAsync(int port)
    {
        var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        await sock.ConnectAsync(IPAddress.Loopback, port);
        var buf = new byte[4096];
        await sock.ReceiveAsync(buf, SocketFlags.None);
        return sock;
    }

    private static void WriteConfigAndReload(NatsServer server, string configPath, string configText)
    {
        File.WriteAllText(configPath, configText);
        server.ReloadConfigOrThrow();
    }

    private static async Task<(NatsServer server, int port, CancellationTokenSource cts, string configPath)>
        StartServerWithConfigAsync(string configContent)
    {
        var port = TestPortAllocator.GetFreePort();
        var configPath = Path.Combine(Path.GetTempPath(), $"natsdotnet-reload-{Guid.NewGuid():N}.conf");
        var finalContent = configContent.Replace("{PORT}", port.ToString());
        File.WriteAllText(configPath, finalContent);

        var options = new NatsOptions { ConfigFile = configPath, Port = port };
        var server = new NatsServer(options, NullLoggerFactory.Instance);
        var cts = new CancellationTokenSource();
        _ = server.StartAsync(cts.Token);
        await server.WaitForReadyAsync();
        return (server, port, cts, configPath);
    }

    private static async Task CleanupAsync(NatsServer server, CancellationTokenSource cts, string configPath)
    {
        await cts.CancelAsync();
        server.Dispose();
        if (File.Exists(configPath)) File.Delete(configPath);
    }

    private static bool ContainsInChain(Exception ex, string substring)
    {
        Exception? current = ex;
        while (current != null)
        {
            if (current.Message.Contains(substring, StringComparison.OrdinalIgnoreCase))
                return true;
            current = current.InnerException;
        }
        return false;
    }

    // ─── Tests: No Config File ──────────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadNoConfigFile server/reload_test.go:116
    /// Reload must fail when the server was started without a config file.
    /// </summary>
    [Fact]
    public async Task Reload_without_config_file_throws()
    {
        var port = TestPortAllocator.GetFreePort();
        var options = new NatsOptions { Port = port };
        var server = new NatsServer(options, NullLoggerFactory.Instance);
        var cts = new CancellationTokenSource();
        _ = server.StartAsync(cts.Token);
        await server.WaitForReadyAsync();

        try
        {
            Should.Throw<InvalidOperationException>(() => server.ReloadConfigOrThrow());
        }
        finally
        {
            await cts.CancelAsync();
            server.Dispose();
        }
    }

    // ─── Tests: Unsupported Changes ─────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadUnsupportedHotSwapping server/reload_test.go:180
    /// Changing the listen port must be rejected (non-reloadable).
    /// </summary>
    [Fact]
    public async Task Reload_port_change_rejected()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            var newPort = TestPortAllocator.GetFreePort();
            File.WriteAllText(configPath, $"port: {newPort}");
            Should.Throw<InvalidOperationException>(() => server.ReloadConfigOrThrow())
                .Message.ShouldContain("Port");
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadInvalidConfig server/reload_test.go:202
    /// Reload with an invalid config file must fail without changing the running config.
    /// </summary>
    [Fact]
    public async Task Reload_invalid_config_rejected()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\ndebug: false");
        try
        {
            // Write invalid config (missing closing brace).
            File.WriteAllText(configPath, $"port: {port}\nauthorization {{\n  user: test\n");
            Should.Throw<Exception>(() => server.ReloadConfigOrThrow());

            // Server should still be operational.
            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Debug / Trace Toggle ────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReload server/reload_test.go:251 (partial — debug/trace portion).
    /// Verifies that debug and trace can be toggled via config reload.
    /// </summary>
    [Fact]
    public async Task Reload_debug_toggle()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\ndebug: false");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\ndebug: true");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();

            WriteConfigAndReload(server, configPath, $"port: {port}\ndebug: false");
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReload server/reload_test.go:251 (partial — trace portion).
    /// </summary>
    [Fact]
    public async Task Reload_trace_toggle()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\ntrace: false");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\ntrace: true");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();

            WriteConfigAndReload(server, configPath, $"port: {port}\ntrace: false");
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReload server/reload_test.go:251 (partial — logtime portion).
    /// </summary>
    [Fact]
    public async Task Reload_logtime_toggle()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nlogtime: false");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nlogtime: true\nlogtime_utc: true");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadLogging server/reload_test.go:4377 (partial — trace_verbose).
    /// </summary>
    [Fact]
    public async Task Reload_trace_verbose_toggle()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\ntrace_verbose: false");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\ntrace_verbose: true");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();

            WriteConfigAndReload(server, configPath, $"port: {port}\ntrace_verbose: false");
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: User Authentication ─────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadRotateUserAuthentication server/reload_test.go:658
    /// Changing username/password must reject old credentials and accept new ones.
    /// </summary>
    [Fact]
    public async Task Reload_rotate_user_authentication()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            "port: {PORT}\nauthorization {\n  user: tyler\n  password: T0pS3cr3t\n}");
        try
        {
            await using var nc = new NatsConnection(new NatsOpts
            {
                Url = $"nats://tyler:T0pS3cr3t@127.0.0.1:{port}",
            });
            await nc.ConnectAsync();
            await nc.PingAsync();

            WriteConfigAndReload(server, configPath,
                $"port: {port}\nauthorization {{\n  user: derek\n  password: passw0rd\n}}");

            await using var oldCreds = new NatsConnection(new NatsOpts
            {
                Url = $"nats://tyler:T0pS3cr3t@127.0.0.1:{port}",
                MaxReconnectRetry = 0,
            });
            var ex = await Should.ThrowAsync<NatsException>(async () =>
            {
                await oldCreds.ConnectAsync();
                await oldCreds.PingAsync();
            });
            ContainsInChain(ex, "Authorization Violation").ShouldBeTrue(
                $"Expected 'Authorization Violation' in exception chain, but got: {ex}");

            await using var newCreds = new NatsConnection(new NatsOpts
            {
                Url = $"nats://derek:passw0rd@127.0.0.1:{port}",
            });
            await newCreds.ConnectAsync();
            await newCreds.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadDisableUserAuthentication server/reload_test.go:781
    /// </summary>
    [Fact]
    public async Task Reload_disable_user_authentication()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            "port: {PORT}\nauthorization {\n  user: tyler\n  password: T0pS3cr3t\n}");
        try
        {
            await using var authConn = new NatsConnection(new NatsOpts
            {
                Url = $"nats://tyler:T0pS3cr3t@127.0.0.1:{port}",
            });
            await authConn.ConnectAsync();
            await authConn.PingAsync();

            WriteConfigAndReload(server, configPath, $"port: {port}");

            await using var noAuthConn = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
            });
            await noAuthConn.ConnectAsync();
            await noAuthConn.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Token Authentication ────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadEnableTokenAuthentication server/reload_test.go:871
    /// </summary>
    [Fact]
    public async Task Reload_enable_token_authentication()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            await using var noAuth = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
            });
            await noAuth.ConnectAsync();
            await noAuth.PingAsync();

            WriteConfigAndReload(server, configPath,
                $"port: {port}\nauthorization {{\n  token: T0pS3cr3t\n}}");

            await using var noTokenConn = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
                MaxReconnectRetry = 0,
            });
            var ex = await Should.ThrowAsync<NatsException>(async () =>
            {
                await noTokenConn.ConnectAsync();
                await noTokenConn.PingAsync();
            });
            ContainsInChain(ex, "Authorization Violation").ShouldBeTrue(
                $"Expected 'Authorization Violation' but got: {ex}");

            await using var tokenConn = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
                AuthOpts = NatsAuthOpts.Default with { Token = "T0pS3cr3t" },
            });
            await tokenConn.ConnectAsync();
            await tokenConn.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadRotateTokenAuthentication server/reload_test.go:814
    /// </summary>
    [Fact]
    public async Task Reload_rotate_token_authentication()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            "port: {PORT}\nauthorization {\n  token: T0pS3cr3t\n}");
        try
        {
            await using var nc = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
                AuthOpts = NatsAuthOpts.Default with { Token = "T0pS3cr3t" },
            });
            await nc.ConnectAsync();
            await nc.PingAsync();

            WriteConfigAndReload(server, configPath,
                $"port: {port}\nauthorization {{\n  token: passw0rd\n}}");

            await using var oldToken = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
                AuthOpts = NatsAuthOpts.Default with { Token = "T0pS3cr3t" },
                MaxReconnectRetry = 0,
            });
            var ex = await Should.ThrowAsync<NatsException>(async () =>
            {
                await oldToken.ConnectAsync();
                await oldToken.PingAsync();
            });
            ContainsInChain(ex, "Authorization Violation").ShouldBeTrue(
                $"Expected 'Authorization Violation' but got: {ex}");

            await using var newToken = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
                AuthOpts = NatsAuthOpts.Default with { Token = "passw0rd" },
            });
            await newToken.ConnectAsync();
            await newToken.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadDisableTokenAuthentication server/reload_test.go:932
    /// </summary>
    [Fact]
    public async Task Reload_disable_token_authentication()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            "port: {PORT}\nauthorization {\n  token: T0pS3cr3t\n}");
        try
        {
            await using var tokenConn = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
                AuthOpts = NatsAuthOpts.Default with { Token = "T0pS3cr3t" },
            });
            await tokenConn.ConnectAsync();
            await tokenConn.PingAsync();

            WriteConfigAndReload(server, configPath, $"port: {port}");

            await using var noAuth = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
            });
            await noAuth.ConnectAsync();
            await noAuth.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Multiple Users Authentication ───────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadEnableUsersAuthentication server/reload_test.go:1052
    /// </summary>
    [Fact]
    public async Task Reload_enable_users_authentication()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            await using var noAuth = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
            });
            await noAuth.ConnectAsync();
            await noAuth.PingAsync();

            WriteConfigAndReload(server, configPath,
                $"port: {port}\nauthorization {{\n  users = [\n    {{user: alice, password: foo}}\n    {{user: bob, password: bar}}\n  ]\n}}");

            await using var noCredConn = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
                MaxReconnectRetry = 0,
            });
            var ex = await Should.ThrowAsync<NatsException>(async () =>
            {
                await noCredConn.ConnectAsync();
                await noCredConn.PingAsync();
            });
            ContainsInChain(ex, "Authorization Violation").ShouldBeTrue(
                $"Expected 'Authorization Violation' but got: {ex}");

            await using var aliceConn = new NatsConnection(new NatsOpts
            {
                Url = $"nats://alice:foo@127.0.0.1:{port}",
            });
            await aliceConn.ConnectAsync();
            await aliceConn.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadRotateUsersAuthentication server/reload_test.go:965
    /// </summary>
    [Fact]
    public async Task Reload_rotate_users_authentication()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            "port: {PORT}\nauthorization {\n  users = [\n    {user: alice, password: foo}\n    {user: bob, password: bar}\n  ]\n}");
        try
        {
            await using var alice = new NatsConnection(new NatsOpts
            {
                Url = $"nats://alice:foo@127.0.0.1:{port}",
            });
            await alice.ConnectAsync();
            await alice.PingAsync();

            WriteConfigAndReload(server, configPath,
                $"port: {port}\nauthorization {{\n  users = [\n    {{user: alice, password: baz}}\n    {{user: bob, password: bar}}\n  ]\n}}");

            await using var oldAlice = new NatsConnection(new NatsOpts
            {
                Url = $"nats://alice:foo@127.0.0.1:{port}",
                MaxReconnectRetry = 0,
            });
            var ex = await Should.ThrowAsync<NatsException>(async () =>
            {
                await oldAlice.ConnectAsync();
                await oldAlice.PingAsync();
            });
            ContainsInChain(ex, "Authorization Violation").ShouldBeTrue(
                $"Expected 'Authorization Violation' but got: {ex}");

            await using var newAlice = new NatsConnection(new NatsOpts
            {
                Url = $"nats://alice:baz@127.0.0.1:{port}",
            });
            await newAlice.ConnectAsync();
            await newAlice.PingAsync();

            await using var bob = new NatsConnection(new NatsOpts
            {
                Url = $"nats://bob:bar@127.0.0.1:{port}",
            });
            await bob.ConnectAsync();
            await bob.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadDisableUsersAuthentication server/reload_test.go:1113
    /// </summary>
    [Fact]
    public async Task Reload_disable_users_authentication()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            "port: {PORT}\nauthorization {\n  users = [\n    {user: alice, password: foo}\n  ]\n}");
        try
        {
            await using var authConn = new NatsConnection(new NatsOpts
            {
                Url = $"nats://alice:foo@127.0.0.1:{port}",
            });
            await authConn.ConnectAsync();
            await authConn.PingAsync();

            WriteConfigAndReload(server, configPath, $"port: {port}");

            await using var noAuth = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
            });
            await noAuth.ConnectAsync();
            await noAuth.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Max Payload ─────────────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadMaxPayload server/reload_test.go:2032
    /// Reducing max_payload must cause oversized publishes on new connections to be rejected.
    /// </summary>
    [Fact]
    public async Task Reload_max_payload_takes_effect()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nmax_payload: 1048576");
        try
        {
            using var sock = await RawConnectAsync(port);
            await sock.SendAsync(Encoding.ASCII.GetBytes("CONNECT {\"verbose\":false,\"pedantic\":false}\r\n"), SocketFlags.None);
            await sock.SendAsync(Encoding.ASCII.GetBytes("SUB foo 1\r\n"), SocketFlags.None);
            await sock.SendAsync(Encoding.ASCII.GetBytes("PING\r\n"), SocketFlags.None);
            await SocketTestHelper.ReadUntilAsync(sock, "PONG");

            await sock.SendAsync(Encoding.ASCII.GetBytes("PUB foo 5\r\nhello\r\n"), SocketFlags.None);
            await sock.SendAsync(Encoding.ASCII.GetBytes("PING\r\n"), SocketFlags.None);
            var response = await SocketTestHelper.ReadUntilAsync(sock, "PONG");
            response.ShouldContain("MSG foo");

            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_payload: 2");

            using var sock2 = await RawConnectAsync(port);
            await sock2.SendAsync(Encoding.ASCII.GetBytes("CONNECT {\"verbose\":false,\"pedantic\":false}\r\n"), SocketFlags.None);
            await sock2.SendAsync(Encoding.ASCII.GetBytes("PUB foo 5\r\nhello\r\n"), SocketFlags.None);
            var errResponse = await SocketTestHelper.ReadUntilAsync(sock2, "-ERR", timeoutMs: 5000);
            errResponse.ShouldContain("-ERR");
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Limits ──────────────────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadMaxControlLineWithClients server/reload_test.go:3946
    /// </summary>
    [Fact]
    public async Task Reload_max_control_line()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nmax_control_line: 4096");
        try
        {
            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();

            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_control_line: 256");

            await using var client2 = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client2.ConnectAsync();
            await client2.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReload server/reload_test.go:251 (partial — ping_interval portion).
    /// </summary>
    [Fact]
    public async Task Reload_ping_interval()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nping_interval: 120");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nping_interval: 5");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReload server/reload_test.go:251 (partial — max_pings_out portion).
    /// </summary>
    [Fact]
    public async Task Reload_max_pings_out()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nmax_pings_out: 2");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_pings_out: 5");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReload server/reload_test.go:251 (partial — write_deadline portion).
    /// </summary>
    [Fact]
    public async Task Reload_write_deadline()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nwrite_deadline: \"10s\"");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nwrite_deadline: \"3s\"");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReload server/reload_test.go:251 (partial — max_pending).
    /// </summary>
    [Fact]
    public async Task Reload_max_pending()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_pending: 1024");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReload server/reload_test.go:251 (partial — auth_timeout portion).
    /// </summary>
    [Fact]
    public async Task Reload_auth_timeout()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            "port: {PORT}\nauthorization {\n  user: tyler\n  password: T0pS3cr3t\n  timeout: 1\n}");
        try
        {
            WriteConfigAndReload(server, configPath,
                $"port: {port}\nauthorization {{\n  user: tyler\n  password: T0pS3cr3t\n  timeout: 5\n}}");

            await using var client = new NatsConnection(new NatsOpts
            {
                Url = $"nats://tyler:T0pS3cr3t@127.0.0.1:{port}",
            });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadClientAdvertise server/reload_test.go:1932
    /// </summary>
    [Fact]
    public async Task Reload_client_advertise()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nclient_advertise: \"me:1\"");
            WriteConfigAndReload(server, configPath, $"port: {port}");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: File Paths ──────────────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadRotateFiles server/reload_test.go:2095 (partial — pid_file).
    /// </summary>
    [Fact]
    public async Task Reload_pid_file_change()
    {
        var pidFile1 = Path.Combine(Path.GetTempPath(), $"natsdotnet-pid1-{Guid.NewGuid():N}.pid");
        var pidFile2 = Path.Combine(Path.GetTempPath(), $"natsdotnet-pid2-{Guid.NewGuid():N}.pid");
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            $"port: {{PORT}}\npid_file: \"{pidFile1.Replace("\\", "\\\\")}\"");
        try
        {
            WriteConfigAndReload(server, configPath,
                $"port: {port}\npid_file: \"{pidFile2.Replace("\\", "\\\\")}\"");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
            if (File.Exists(pidFile1)) File.Delete(pidFile1);
            if (File.Exists(pidFile2)) File.Delete(pidFile2);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadRotateFiles server/reload_test.go:2095 (partial — log_file).
    /// </summary>
    [Fact]
    public async Task Reload_log_file_change()
    {
        var logFile1 = Path.Combine(Path.GetTempPath(), $"natsdotnet-log1-{Guid.NewGuid():N}.log");
        var logFile2 = Path.Combine(Path.GetTempPath(), $"natsdotnet-log2-{Guid.NewGuid():N}.log");
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            $"port: {{PORT}}\nlog_file: \"{logFile1.Replace("\\", "\\\\")}\"");
        try
        {
            WriteConfigAndReload(server, configPath,
                $"port: {port}\nlog_file: \"{logFile2.Replace("\\", "\\\\")}\"");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
            if (File.Exists(logFile1)) File.Delete(logFile1);
            if (File.Exists(logFile2)) File.Delete(logFile2);
        }
    }

    /// <summary>
    /// Changing log_size_limit via reload must take effect.
    /// </summary>
    [Fact]
    public async Task Reload_log_size_limit()
    {
        var logFile = Path.Combine(Path.GetTempPath(), $"natsdotnet-logsize-{Guid.NewGuid():N}.log");
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            $"port: {{PORT}}\nlog_file: \"{logFile.Replace("\\", "\\\\")}\"");
        try
        {
            WriteConfigAndReload(server, configPath,
                $"port: {port}\nlog_file: \"{logFile.Replace("\\", "\\\\")}\"\nlog_size_limit: 1048576");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
            if (File.Exists(logFile)) File.Delete(logFile);
        }
    }

    /// <summary>
    /// Changing log_max_files via reload must take effect.
    /// </summary>
    [Fact]
    public async Task Reload_log_max_files()
    {
        var logFile = Path.Combine(Path.GetTempPath(), $"natsdotnet-logmax-{Guid.NewGuid():N}.log");
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            $"port: {{PORT}}\nlog_file: \"{logFile.Replace("\\", "\\\\")}\"");
        try
        {
            WriteConfigAndReload(server, configPath,
                $"port: {port}\nlog_file: \"{logFile.Replace("\\", "\\\\")}\"\nlog_max_files: 5");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
            if (File.Exists(logFile)) File.Delete(logFile);
        }
    }

    // ─── Tests: Connect Error Reports ───────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadConnectErrReports server/reload_test.go:4193
    /// </summary>
    [Fact]
    public async Task Reload_connect_error_reports()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath,
                $"port: {port}\nconnect_error_reports: 2\nreconnect_error_reports: 3");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadConnectErrReports server/reload_test.go:4193 (reconnect_error_reports).
    /// </summary>
    [Fact]
    public async Task Reload_reconnect_error_reports()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nreconnect_error_reports: 5");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Max Connections ─────────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadMaxConnections server/reload_test.go:1978 (extended).
    /// Increasing max_connections after reducing it should allow new connections.
    /// </summary>
    [Fact]
    public async Task Reload_max_connections_increase_allows_new_connections()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nmax_connections: 65536");
        try
        {
            using var c1 = await RawConnectAsync(port);
            server.ClientCount.ShouldBe(1);

            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_connections: 1");

            using var c2 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            await c2.ConnectAsync(IPAddress.Loopback, port);
            var response = await SocketTestHelper.ReadUntilAsync(c2, "-ERR", timeoutMs: 5000);
            response.ShouldContain("maximum connections exceeded");

            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_connections: 10");

            using var c3 = await RawConnectAsync(port);
            server.ClientCount.ShouldBeGreaterThanOrEqualTo(2);
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadMaxConnections server/reload_test.go:1978
    /// Reducing max_connections below the current client count must reject new connections.
    /// </summary>
    [Fact]
    public async Task Reload_max_connections_below_current_rejects_new()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nmax_connections: 65536");
        try
        {
            using var c1 = await RawConnectAsync(port);
            using var c2 = await RawConnectAsync(port);
            using var c3 = await RawConnectAsync(port);
            server.ClientCount.ShouldBe(3);

            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_connections: 2");

            using var c4 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            await c4.ConnectAsync(IPAddress.Loopback, port);
            var response = await SocketTestHelper.ReadUntilAsync(c4, "-ERR", timeoutMs: 5000);
            response.ShouldContain("maximum connections exceeded");
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Unchanged Config ────────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadAccountWithNoChanges server/reload_test.go:2887
    /// Reloading an identical config must be a no-op.
    /// </summary>
    [Fact]
    public async Task Reload_unchanged_config_is_noop()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\ndebug: false");
        try
        {
            server.ReloadConfigOrThrow();

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Multiple Sequential Reloads ─────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadLogging server/reload_test.go:4377 (simplified).
    /// Multiple sequential reloads with different logging settings must all succeed.
    /// </summary>
    [Fact]
    public async Task Reload_multiple_sequential_logging_reloads()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\ndebug: false\ntrace: false");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\ndebug: true\ntrace: false");
            WriteConfigAndReload(server, configPath, $"port: {port}\ndebug: false\ntrace: true");
            WriteConfigAndReload(server, configPath, $"port: {port}\ndebug: false\ntrace: false");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReload server/reload_test.go:251 (combined — auth + max payload).
    /// </summary>
    [Fact]
    public async Task Reload_combined_auth_and_limits()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nmax_payload: 1048576");
        try
        {
            await using var noAuth = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await noAuth.ConnectAsync();
            await noAuth.PingAsync();

            WriteConfigAndReload(server, configPath,
                $"port: {port}\nmax_payload: 1024\nauthorization {{\n  user: tyler\n  password: T0pS3cr3t\n}}");

            await using var noAuthPost = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
                MaxReconnectRetry = 0,
            });
            await Should.ThrowAsync<NatsException>(async () =>
            {
                await noAuthPost.ConnectAsync();
                await noAuthPost.PingAsync();
            });

            await using var authConn = new NatsConnection(new NatsOpts
            {
                Url = $"nats://tyler:T0pS3cr3t@127.0.0.1:{port}",
            });
            await authConn.ConnectAsync();
            await authConn.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Max Subs ────────────────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadMaxSubsUnsupported server/reload_test.go:1917
    /// </summary>
    [Fact]
    public async Task Reload_max_subs()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nmax_subs: 0");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_subs: 10");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Changing max_sub_tokens via reload must take effect.
    /// </summary>
    [Fact]
    public async Task Reload_max_sub_tokens()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_sub_tokens: 16");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Server Name ─────────────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadUnsupported server/reload_test.go:129 (server_name).
    /// </summary>
    [Fact]
    public async Task Reload_server_name_change_rejected()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nserver_name: alpha");
        try
        {
            File.WriteAllText(configPath, $"port: {port}\nserver_name: beta");
            Should.Throw<InvalidOperationException>(() => server.ReloadConfigOrThrow())
                .Message.ShouldContain("ServerName");
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Lame Duck ───────────────────────────────────────────────────

    /// <summary>
    /// Changing lame_duck_duration via reload.
    /// </summary>
    [Fact]
    public async Task Reload_lame_duck_duration()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nlame_duck_duration: \"30s\"");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Changing lame_duck_grace_period via reload.
    /// </summary>
    [Fact]
    public async Task Reload_lame_duck_grace_period()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nlame_duck_grace_period: \"5s\"");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Pub/Sub After Reload ────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReload server/reload_test.go:251 (validation that pub/sub works post-reload).
    /// </summary>
    [Fact]
    public async Task Reload_pubsub_still_works_after_reload()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\ndebug: false");
        try
        {
            await using var sub = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await sub.ConnectAsync();
            await using var subscription = await sub.SubscribeCoreAsync<string>("test.subject");
            await sub.PingAsync();

            await using var pub = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await pub.ConnectAsync();

            await pub.PublishAsync("test.subject", "before-reload");

            using var cts1 = new CancellationTokenSource(TimeSpan.FromSeconds(5));
            var msg = await subscription.Msgs.ReadAsync(cts1.Token);
            msg.Data.ShouldBe("before-reload");

            WriteConfigAndReload(server, configPath, $"port: {port}\ndebug: true");
            await Task.Delay(100);

            await pub.PublishAsync("test.subject", "after-reload");

            using var cts2 = new CancellationTokenSource(TimeSpan.FromSeconds(5));
            msg = await subscription.Msgs.ReadAsync(cts2.Token);
            msg.Data.ShouldBe("after-reload");
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Account Users ───────────────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadAccountUsers server/reload_test.go:2670 (simplified).
    /// </summary>
    [Fact]
    public async Task Reload_account_user_changes()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            "port: {PORT}\naccounts {\n  acctA {\n    users = [\n      {user: derek, password: derek}\n    ]\n  }\n}");
        try
        {
            await using var derek = new NatsConnection(new NatsOpts
            {
                Url = $"nats://derek:derek@127.0.0.1:{port}",
            });
            await derek.ConnectAsync();
            await derek.PingAsync();

            WriteConfigAndReload(server, configPath,
                $"port: {port}\naccounts {{\n  acctA {{\n    users = [\n      {{user: derek, password: derek}}\n      {{user: ivan, password: ivan}}\n    ]\n  }}\n}}");

            await derek.PingAsync();

            await using var ivan = new NatsConnection(new NatsOpts
            {
                Url = $"nats://ivan:ivan@127.0.0.1:{port}",
            });
            await ivan.ConnectAsync();
            await ivan.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Cluster Config Changes ──────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadClusterPortUnsupported server/reload_test.go:1394
    /// </summary>
    [Fact]
    public async Task Reload_cluster_port_change_rejected()
    {
        var clusterPort = TestPortAllocator.GetFreePort();
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            $"port: {{PORT}}\ncluster {{\n  host: 127.0.0.1\n  port: {clusterPort}\n}}");
        try
        {
            var newClusterPort = TestPortAllocator.GetFreePort();
            File.WriteAllText(configPath,
                $"port: {port}\ncluster {{\n  host: 127.0.0.1\n  port: {newClusterPort}\n}}");
            Should.Throw<InvalidOperationException>(() => server.ReloadConfigOrThrow())
                .Message.ShouldContain("Cluster");
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReloadClusterName server/reload_test.go:1893
    /// </summary>
    [Fact]
    public async Task Reload_cluster_name_change_rejected()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            "port: {PORT}\ncluster {\n  name: abc\n  host: 127.0.0.1\n  port: -1\n}");
        try
        {
            File.WriteAllText(configPath,
                $"port: {port}\ncluster {{\n  name: xyz\n  host: 127.0.0.1\n  port: -1\n}}");
            Should.Throw<InvalidOperationException>(() => server.ReloadConfigOrThrow())
                .Message.ShouldContain("Cluster");
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: JetStream StoreDir ──────────────────────────────────────────

    /// <summary>
    /// JetStream.StoreDir is non-reloadable.
    /// </summary>
    [Fact]
    public async Task Reload_jetstream_store_dir_change_rejected()
    {
        var storeDir1 = Path.Combine(Path.GetTempPath(), $"nats-js-1-{Guid.NewGuid():N}");
        var storeDir2 = Path.Combine(Path.GetTempPath(), $"nats-js-2-{Guid.NewGuid():N}");
        Directory.CreateDirectory(storeDir1);
        var (server, port, cts, configPath) = await StartServerWithConfigAsync(
            $"port: {{PORT}}\njetstream {{\n  store_dir: \"{storeDir1.Replace("\\", "\\\\")}\"\n}}");
        try
        {
            File.WriteAllText(configPath,
                $"port: {port}\njetstream {{\n  store_dir: \"{storeDir2.Replace("\\", "\\\\")}\"\n}}");
            Should.Throw<InvalidOperationException>(() => server.ReloadConfigOrThrow())
                .Message.ShouldContain("JetStream.StoreDir");
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
            if (Directory.Exists(storeDir1)) Directory.Delete(storeDir1, true);
            if (Directory.Exists(storeDir2)) Directory.Delete(storeDir2, true);
        }
    }

    // ─── Tests: CLI Override Preservation ────────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadBoolFlags server/reload_test.go:3480 (simplified).
    /// </summary>
    [Fact]
    public async Task Reload_cli_overrides_preserved()
    {
        var port = TestPortAllocator.GetFreePort();
        var configPath = Path.Combine(Path.GetTempPath(), $"natsdotnet-cli-{Guid.NewGuid():N}.conf");
        File.WriteAllText(configPath, $"port: {port}\ndebug: false");

        var options = new NatsOptions { ConfigFile = configPath, Port = port, Debug = true };
        options.InCmdLine.Add("Debug");

        var server = new NatsServer(options, NullLoggerFactory.Instance);
        var cliSnapshot = new NatsOptions { Debug = true };
        server.SetCliSnapshot(cliSnapshot, new HashSet<string> { "Debug" });

        var cts = new CancellationTokenSource();
        _ = server.StartAsync(cts.Token);
        await server.WaitForReadyAsync();

        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\ndebug: false");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await cts.CancelAsync();
            server.Dispose();
            if (File.Exists(configPath)) File.Delete(configPath);
        }
    }

    // ─── Tests: Misc Reloadable Options ─────────────────────────────────────

    /// <summary>
    /// Changing syslog settings via reload.
    /// Go: TestConfigReload server/reload_test.go:251 (partial — syslog portion).
    /// </summary>
    [Fact]
    public async Task Reload_syslog_settings()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nsyslog: false");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nsyslog: true");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Go: TestConfigReload server/reload_test.go:251 (partial — remote_syslog).
    /// </summary>
    [Fact]
    public async Task Reload_remote_syslog()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath,
                $"port: {port}\nremote_syslog: \"udp://127.0.0.1:514\"");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Changing no_header_support via reload.
    /// </summary>
    [Fact]
    public async Task Reload_no_header_support()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nno_header_support: true");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Changing disable_sublist_cache via reload.
    /// </summary>
    [Fact]
    public async Task Reload_disable_sublist_cache()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\ndisable_sublist_cache: true");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Changing no_sys_acc via reload.
    /// </summary>
    [Fact]
    public async Task Reload_no_system_account()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nno_sys_acc: true");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Changing max_closed_clients via reload.
    /// </summary>
    [Fact]
    public async Task Reload_max_closed_clients()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_closed_clients: 500");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Changing max_traced_msg_len via reload.
    /// </summary>
    [Fact]
    public async Task Reload_max_traced_msg_len()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_traced_msg_len: 1024");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Changing tags via reload.
    /// </summary>
    [Fact]
    public async Task Reload_tags_change()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            WriteConfigAndReload(server, configPath, $"port: {port}\ntags: {{ region: \"us-east-1\" }}");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Rapid Reload Cycles ─────────────────────────────────────────

    /// <summary>
    /// Verifies that the server handles many rapid sequential reloads without
    /// errors or instability.
    /// </summary>
    [Fact]
    public async Task Reload_rapid_sequential_reloads()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\ndebug: false");
        try
        {
            for (int i = 0; i < 20; i++)
            {
                WriteConfigAndReload(server, configPath, $"port: {port}\ndebug: {(i % 2 == 0).ToString().ToLowerInvariant()}");
            }

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Auth + Existing Connections ─────────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadEnableUserAuthentication server/reload_test.go:720
    /// Enabling auth with existing connections.
    /// </summary>
    [Fact]
    public async Task Reload_enable_auth_with_existing_connections()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            using var rawConn1 = await RawConnectAsync(port);
            using var rawConn2 = await RawConnectAsync(port);
            server.ClientCount.ShouldBe(2);

            WriteConfigAndReload(server, configPath,
                $"port: {port}\nauthorization {{\n  user: test\n  password: secret\n}}");

            await using var authConn = new NatsConnection(new NatsOpts
            {
                Url = $"nats://test:secret@127.0.0.1:{port}",
            });
            await authConn.ConnectAsync();
            await authConn.PingAsync();

            await using var noAuth = new NatsConnection(new NatsOpts
            {
                Url = $"nats://127.0.0.1:{port}",
                MaxReconnectRetry = 0,
            });
            await Should.ThrowAsync<NatsException>(async () =>
            {
                await noAuth.ConnectAsync();
                await noAuth.PingAsync();
            });
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Concurrent Connections During Reload ────────────────────────

    /// <summary>
    /// Verifies that connections established during a reload cycle are handled gracefully.
    /// </summary>
    [Fact]
    public async Task Reload_concurrent_connections_during_reload()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\ndebug: false");
        try
        {
            var tasks = new List<Task>();

            for (int i = 0; i < 5; i++)
            {
                tasks.Add(Task.Run(async () =>
                {
                    await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
                    await client.ConnectAsync();
                    await client.PingAsync();
                }));
            }

            WriteConfigAndReload(server, configPath, $"port: {port}\ndebug: true");

            await Task.WhenAll(tasks);

            await using var postReload = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await postReload.ConnectAsync();
            await postReload.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Reload After Connections Served ─────────────────────────────

    /// <summary>
    /// Go: TestConfigReloadAndVarz server/reload_test.go:4144 (simplified).
    /// </summary>
    [Fact]
    public async Task Reload_after_connections_served()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}\nmax_connections: 65536");
        try
        {
            for (int i = 0; i < 5; i++)
            {
                await using var conn = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
                await conn.ConnectAsync();
                await conn.PingAsync();
            }

            WriteConfigAndReload(server, configPath, $"port: {port}\nmax_connections: 100");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    // ─── Tests: Monitor Port ────────────────────────────────────────────────

    /// <summary>
    /// Changing monitor_port (http_port) via reload.
    /// </summary>
    [Fact]
    public async Task Reload_monitor_port()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            var monPort = TestPortAllocator.GetFreePort();
            WriteConfigAndReload(server, configPath, $"port: {port}\nhttp_port: {monPort}");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }

    /// <summary>
    /// Changing prof_port via reload.
    /// </summary>
    [Fact]
    public async Task Reload_prof_port()
    {
        var (server, port, cts, configPath) = await StartServerWithConfigAsync("port: {PORT}");
        try
        {
            var profPort = TestPortAllocator.GetFreePort();
            WriteConfigAndReload(server, configPath, $"port: {port}\nprof_port: {profPort}");

            await using var client = new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
            await client.ConnectAsync();
            await client.PingAsync();
        }
        finally
        {
            await CleanupAsync(server, cts, configPath);
        }
    }
}
