// Copyright 2012-2026 The NATS Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Mirrors Go natsConnect helpers from test files.

using NATS.Client.Core;
using ZB.MOM.NatsNet.Server;

namespace ZB.MOM.NatsNet.Server.IntegrationTests.Helpers;

/// <summary>
/// NATS.Client.Core wrapper helpers for integration test connections.
/// Mirrors Go <c>natsConnect</c> pattern from test helper files.
/// </summary>
internal static class NatsTestClient
{
    // Default test connection options applied unless overridden.
    private static readonly NatsOpts DefaultTestOpts = new()
    {
        Name           = "test-client",
        ConnectTimeout = TimeSpan.FromSeconds(5),
        RequestTimeout = TimeSpan.FromSeconds(10),
    };

    /// <summary>
    /// Creates a <see cref="NatsConnection"/> to the given <paramref name="url"/> with
    /// sensible test defaults. Settings in <paramref name="opts"/> override the defaults.
    /// </summary>
    public static NatsConnection Connect(string url, NatsOpts? opts = null)
    {
        var effective = opts ?? DefaultTestOpts;

        // Always override the URL; apply default name when not supplied.
        effective = effective with { Url = url };
        if (string.IsNullOrEmpty(effective.Name))
            effective = effective with { Name = DefaultTestOpts.Name };

        return new NatsConnection(effective);
    }

    /// <summary>
    /// Creates a <see cref="NatsConnection"/> to the given <paramref name="server"/>.
    /// The URL is derived from the server's client port — uses the value from
    /// <see cref="ServerOptions.Port"/> (resolved during server setup). When the server
    /// was configured with port -1 (random), the actual port is stored in
    /// <see cref="ServerOptions.Port"/> after Start().
    /// </summary>
    public static NatsConnection ConnectToServer(NatsServer server, NatsOpts? opts = null)
    {
        var port = server.Options.Port;
        // Fallback to well-known port if options still show 0 or -1.
        if (port <= 0) port = 4222;

        return Connect($"nats://127.0.0.1:{port}", opts);
    }
}
