using NATS.NKeys;
using NATS.Server.Auth;
using NATS.Server.Protocol;

namespace NATS.Server.Auth.Tests.Auth;

public class AuthServiceParityBatch4Tests
{
    [Fact]
    public void Build_assigns_global_account_to_orphan_users()
    {
        var service = AuthService.Build(new NatsOptions
        {
            Users = [new User { Username = "alice", Password = "secret" }],
        });

        var result = service.Authenticate(new ClientAuthContext
        {
            Opts = new ClientOptions { Username = "alice", Password = "secret" },
            Nonce = [],
        });

        result.ShouldNotBeNull();
        result.AccountName.ShouldBe(Account.GlobalAccountName);
    }

    [Fact]
    public void Build_assigns_global_account_to_orphan_nkeys()
    {
        using var kp = KeyPair.CreatePair(PrefixByte.User);
        var pub = kp.GetPublicKey();
        var nonce = "test-nonce"u8.ToArray();
        var sig = new byte[64];
        kp.Sign(nonce, sig);

        var service = AuthService.Build(new NatsOptions
        {
            NKeys = [new NKeyUser { Nkey = pub }],
        });

        var result = service.Authenticate(new ClientAuthContext
        {
            Opts = new ClientOptions
            {
                Nkey = pub,
                Sig = Convert.ToBase64String(sig),
            },
            Nonce = nonce,
        });

        result.ShouldNotBeNull();
        result.AccountName.ShouldBe(Account.GlobalAccountName);
    }

    [Fact]
    public void Build_validates_response_permissions_defaults_and_publish_allow()
    {
        var service = AuthService.Build(new NatsOptions
        {
            Users =
            [
                new User
                {
                    Username = "alice",
                    Password = "secret",
                    Permissions = new Permissions
                    {
                        Response = new ResponsePermission { MaxMsgs = 0, Expires = TimeSpan.Zero },
                    },
                },
            ],
        });

        var result = service.Authenticate(new ClientAuthContext
        {
            Opts = new ClientOptions { Username = "alice", Password = "secret" },
            Nonce = [],
        });

        result.ShouldNotBeNull();
        result.Permissions.ShouldNotBeNull();
        result.Permissions.Response.ShouldNotBeNull();
        result.Permissions.Response.MaxMsgs.ShouldBe(NatsProtocol.DefaultAllowResponseMaxMsgs);
        result.Permissions.Response.Expires.ShouldBe(NatsProtocol.DefaultAllowResponseExpiration);
        result.Permissions.Publish.ShouldNotBeNull();
        result.Permissions.Publish.Allow.ShouldNotBeNull();
        result.Permissions.Publish.Allow.Count.ShouldBe(0);
    }
}
