using NATS.Client.Core;

namespace NATS.Server.Benchmark.Tests.Infrastructure;

/// <summary>
/// Starts both a Go and .NET NATS server for core pub/sub benchmarks.
/// Shared across all tests in the "Benchmark-Core" collection.
/// </summary>
public sealed class CoreServerPairFixture : IAsyncLifetime
{
    private GoServerProcess? _goServer;
    private DotNetServerProcess? _dotNetServer;

    public int GoPort => _goServer?.Port ?? throw new InvalidOperationException("Go server not started");
    public int DotNetPort => _dotNetServer?.Port ?? throw new InvalidOperationException(".NET server not started");
    public bool GoAvailable => _goServer is not null;

    public async Task InitializeAsync()
    {
        _dotNetServer = new DotNetServerProcess();
        var dotNetTask = _dotNetServer.StartAsync();

        if (GoServerProcess.IsAvailable())
        {
            _goServer = new GoServerProcess();
            await Task.WhenAll(dotNetTask, _goServer.StartAsync());
        }
        else
        {
            await dotNetTask;
        }
    }

    public async Task DisposeAsync()
    {
        if (_goServer is not null)
            await _goServer.DisposeAsync();
        if (_dotNetServer is not null)
            await _dotNetServer.DisposeAsync();
    }

    public NatsConnection CreateGoClient()
        => new(new NatsOpts { Url = $"nats://127.0.0.1:{GoPort}" });

    public NatsConnection CreateDotNetClient()
        => new(new NatsOpts { Url = $"nats://127.0.0.1:{DotNetPort}" });
}
