using NATS.Server.Auth;
using NATS.Server.Imports;
using NATS.Server.Subscriptions;

namespace NATS.Server.Auth.Tests.Auth;

public class AccountResponseAndInterestParityBatch1Tests
{
    [Fact]
    public void ClientInfoHdr_constant_matches_go_value()
    {
        Account.ClientInfoHdr.ShouldBe("Nats-Request-Info");
    }

    [Fact]
    public void Interest_and_subscription_interest_count_plain_and_queue_matches()
    {
        using var account = new Account("A");
        account.SubList.Insert(new Subscription { Subject = "orders.*", Sid = "1" });
        account.SubList.Insert(new Subscription { Subject = "orders.*", Sid = "2", Queue = "workers" });

        account.Interest("orders.created").ShouldBe(2);
        account.SubscriptionInterest("orders.created").ShouldBeTrue();
        account.SubscriptionInterest("payments.created").ShouldBeFalse();
    }

    [Fact]
    public void NumServiceImports_counts_distinct_from_subject_keys()
    {
        using var importer = new Account("importer");
        using var exporter = new Account("exporter");

        importer.Imports.AddServiceImport(new ServiceImport
        {
            DestinationAccount = exporter,
            From = "svc.a",
            To = "svc.remote.a",
        });
        importer.Imports.AddServiceImport(new ServiceImport
        {
            DestinationAccount = exporter,
            From = "svc.a",
            To = "svc.remote.b",
        });
        importer.Imports.AddServiceImport(new ServiceImport
        {
            DestinationAccount = exporter,
            From = "svc.b",
            To = "svc.remote.c",
        });

        importer.NumServiceImports().ShouldBe(2);
    }

    [Fact]
    public void NumPendingResponses_filters_by_service_export()
    {
        using var account = new Account("A");
        account.AddServiceExport("svc.one", ServiceResponseType.Singleton, null);
        account.AddServiceExport("svc.two", ServiceResponseType.Singleton, null);

        var seOne = account.Exports.Services["svc.one"];
        var seTwo = account.Exports.Services["svc.two"];

        account.Exports.Responses["r1"] = new ServiceImport
        {
            DestinationAccount = account,
            From = "_R_.AAA.>",
            To = "reply.one",
            Export = seOne,
            IsResponse = true,
        };
        account.Exports.Responses["r2"] = new ServiceImport
        {
            DestinationAccount = account,
            From = "_R_.BBB.>",
            To = "reply.two",
            Export = seOne,
            IsResponse = true,
        };
        account.Exports.Responses["r3"] = new ServiceImport
        {
            DestinationAccount = account,
            From = "_R_.CCC.>",
            To = "reply.three",
            Export = seTwo,
            IsResponse = true,
        };

        account.NumPendingAllResponses().ShouldBe(3);
        account.NumPendingResponses("svc.one").ShouldBe(2);
        account.NumPendingResponses("svc.two").ShouldBe(1);
        account.NumPendingResponses("svc.unknown").ShouldBe(0);
    }

    [Fact]
    public void RemoveRespServiceImport_removes_mapping_for_specified_reason()
    {
        using var account = new Account("A");
        account.AddServiceExport("svc.one", ServiceResponseType.Singleton, null);
        var seOne = account.Exports.Services["svc.one"];

        var responseSi = new ServiceImport
        {
            DestinationAccount = account,
            From = "_R_.ZZZ.>",
            To = "reply",
            Export = seOne,
            IsResponse = true,
        };
        account.Exports.Responses["r1"] = responseSi;

        account.RemoveRespServiceImport(responseSi, ResponseServiceImportRemovalReason.Timeout);

        account.Exports.Responses.Count.ShouldBe(0);
    }
}
