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

namespace NATS.Server.Tests;

public class SimpleUserPasswordAuthenticatorTests
{
    [Fact]
    public void Returns_result_for_correct_credentials()
    {
        var auth = new SimpleUserPasswordAuthenticator("admin", "password123");
        var ctx = new ClientAuthContext
        {
            Opts = new ClientOptions { Username = "admin", Password = "password123" },
            Nonce = [],
        };

        var result = auth.Authenticate(ctx);

        result.ShouldNotBeNull();
        result.Identity.ShouldBe("admin");
    }

    [Fact]
    public void Returns_null_for_wrong_username()
    {
        var auth = new SimpleUserPasswordAuthenticator("admin", "password123");
        var ctx = new ClientAuthContext
        {
            Opts = new ClientOptions { Username = "wrong", Password = "password123" },
            Nonce = [],
        };

        auth.Authenticate(ctx).ShouldBeNull();
    }

    [Fact]
    public void Returns_null_for_wrong_password()
    {
        var auth = new SimpleUserPasswordAuthenticator("admin", "password123");
        var ctx = new ClientAuthContext
        {
            Opts = new ClientOptions { Username = "admin", Password = "wrong" },
            Nonce = [],
        };

        auth.Authenticate(ctx).ShouldBeNull();
    }

    [Fact]
    public void Returns_null_for_null_username()
    {
        var auth = new SimpleUserPasswordAuthenticator("admin", "password123");
        var ctx = new ClientAuthContext
        {
            Opts = new ClientOptions { Username = null, Password = "password123" },
            Nonce = [],
        };

        auth.Authenticate(ctx).ShouldBeNull();
    }

    [Fact]
    public void Returns_null_for_empty_username()
    {
        var auth = new SimpleUserPasswordAuthenticator("admin", "password123");
        var ctx = new ClientAuthContext
        {
            Opts = new ClientOptions { Username = "", Password = "password123" },
            Nonce = [],
        };

        auth.Authenticate(ctx).ShouldBeNull();
    }

    [Fact]
    public void Returns_null_for_null_password()
    {
        var auth = new SimpleUserPasswordAuthenticator("admin", "password123");
        var ctx = new ClientAuthContext
        {
            Opts = new ClientOptions { Username = "admin", Password = null },
            Nonce = [],
        };

        auth.Authenticate(ctx).ShouldBeNull();
    }

    [Fact]
    public void Supports_bcrypt_password()
    {
        var hash = BCrypt.Net.BCrypt.HashPassword("secret");
        var auth = new SimpleUserPasswordAuthenticator("admin", hash);
        var ctx = new ClientAuthContext
        {
            Opts = new ClientOptions { Username = "admin", Password = "secret" },
            Nonce = [],
        };

        auth.Authenticate(ctx).ShouldNotBeNull();
    }

    [Fact]
    public void Rejects_wrong_password_with_bcrypt()
    {
        var hash = BCrypt.Net.BCrypt.HashPassword("secret");
        var auth = new SimpleUserPasswordAuthenticator("admin", hash);
        var ctx = new ClientAuthContext
        {
            Opts = new ClientOptions { Username = "admin", Password = "wrongpassword" },
            Nonce = [],
        };

        auth.Authenticate(ctx).ShouldBeNull();
    }
}
