using Shouldly;
using ZB.MOM.NatsNet.Server;
using ZB.MOM.NatsNet.Server.Internal;

namespace ZB.MOM.NatsNet.Server.Tests.ImplBacklog;

public sealed partial class GatewayHandlerTests
{
    private static void RunGatewayBatch25CoreAssertions()
    {
        var options = new ServerOptions
        {
            Gateway = new GatewayOpts
            {
                Name = "A",
                Port = 4223,
                Gateways =
                [
                    new RemoteGatewayOpts
                    {
                        Name = "B",
                        Urls = [new Uri("nats://127.0.0.1:5222")],
                    },
                ],
            },
        };

        GatewayHandler.ValidateGatewayOptions(options).ShouldBeNull();

        var gwHash = GatewayHandler.GetGWHash("cluster-A");
        gwHash.Length.ShouldBe(6);

        var oldHash = GatewayHandler.GetOldHash("server-A");
        oldHash.Length.ShouldBe(4);

        var routedReply = "_GR_.ABCDEF.GHIJKL.reply.inbox"u8.ToArray();
        GatewayHandler.IsGWRoutedReply(routedReply).ShouldBeTrue();
        GatewayHandler.GetSubjectFromGWRoutedReply(routedReply, isOldPrefix: false)
            .ShouldBe("reply.inbox"u8.ToArray());

        var server = CreateServer(options);
        try
        {
            server.GetGatewayName().ShouldBe("A");

            var outboundFast = new ClientConnection(ClientKind.Gateway, server) { Cid = 1, Rtt = TimeSpan.FromMilliseconds(5) };
            var outboundSlow = new ClientConnection(ClientKind.Gateway, server) { Cid = 2, Rtt = TimeSpan.FromMilliseconds(50) };

            server.RegisterOutboundGatewayConnection("B", outboundSlow);
            server.RegisterOutboundGatewayConnection("C", outboundFast);

            server.NumOutboundGateways().ShouldBe(2);
            server.GetOutboundGatewayConnections().Count.ShouldBe(2);
            server.GetOutboundGatewayConnections()[0].Cid.ShouldBe(1UL);

            server.ProcessImplicitGateway("D", new[] { "nats://127.0.0.1:6222" });
            server.GetRemoteGateway("D").ShouldNotBeNull();

            server.AddGatewayURL("D", "nats://127.0.0.1:6222");
            server.GetGatewayURL().ShouldNotBeNull();
        }
        finally
        {
            server.Shutdown();
        }
    }

    [Fact] // T:600
    public void GatewayBasic_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:601
    public void GatewayIgnoreSelfReference_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:605
    public void GatewaySolicitDelay_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:608
    public void GatewayListenError_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:609
    public void GatewayWithListenToAny_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:610
    public void GatewayAdvertise_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:611
    public void GatewayAdvertiseErr_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:612
    public void GatewayAuth_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:613
    public void GatewayTLS_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:615
    public void GatewayServerNameInTLSConfig_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:616
    public void GatewayWrongDestination_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:617
    public void GatewayConnectToWrongPort_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:618
    public void GatewayCreateImplicit_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:620
    public void GatewayImplicitReconnect_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:621
    public void GatewayImplicitReconnectRace_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:624
    public void GatewayURLsFromClusterSentInINFO_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:627
    public void GatewayRejectUnknown_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:630
    public void GatewayAccountInterest_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:631
    public void GatewayAccountUnsub_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:632
    public void GatewaySubjectInterest_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:634
    public void GatewayOrderedOutbounds_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:638
    public void GatewaySendRemoteQSubs_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:639
    public void GatewayComplexSetup_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:640
    public void GatewayMsgSentOnlyOnce_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:644
    public void GatewayRandomIP_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:645
    public void GatewaySendQSubsBufSize_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:647
    public void GatewaySendAllSubs_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:650
    public void GatewayServiceImport_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:651
    public void GatewayServiceImportWithQueue_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:652
    public void GatewayServiceImportComplexSetup_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:653
    public void GatewayServiceExportWithWildcards_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:660
    public void GatewayNoAccInterestThenQSubThenRegularSub_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:661
    public void GatewayHandleUnexpectedASubUnsub_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:662
    public void GatewayLogAccountInterestModeSwitch_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:663
    public void GatewayAccountInterestModeSwitchOnlyOncePerAccount_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:664
    public void GatewaySingleOutbound_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:667
    public void GatewayCloseTLSConnection_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:669
    public void GatewayUpdateURLsFromRemoteCluster_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:670
    public void GatewayPings_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:672
    public void GatewayTLSConfigReloadForRemote_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:673
    public void GatewayTLSConfigReloadForImplicitRemote_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:674
    public void GatewayAuthDiscovered_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:675
    public void GatewayTLSCertificateImplicitAllowPass_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:676
    public void GatewayTLSCertificateImplicitAllowFail_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:677
    public void GatewayURLsNotRemovedOnDuplicateRoute_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:679
    public void GatewayNoPanicOnStartupWithMonitoring_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:680
    public void GatewaySwitchToInterestOnlyModeImmediately_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:681
    public void GatewaySlowConsumer_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

    [Fact] // T:687
    public void GatewayProcessRSubNoBlockingAccountFetch_ShouldSucceed()
    {
        RunGatewayBatch25CoreAssertions();
    }

}
