using System;
using StellaOps.Authority.Plugins.Abstractions;
using StellaOps.Cryptography.Audit;

namespace StellaOps.Authority.Plugins.Abstractions.Tests;

public class AuthorityCredentialVerificationResultTests
{
    [Fact]
    public void Success_SetsUserAndClearsFailure()
    {
        var user = new AuthorityUserDescriptor("subject-1", "user", "User", false);

        var auditProperties = new[]
        {
            new AuthEventProperty { Name = "test", Value = ClassifiedString.Public("value") }
        };

        var result = AuthorityCredentialVerificationResult.Success(user, "ok", auditProperties);

        Assert.True(result.Succeeded);
        Assert.Equal(user, result.User);
        Assert.Null(result.FailureCode);
        Assert.Equal("ok", result.Message);
        Assert.Collection(result.AuditProperties, property => Assert.Equal("test", property.Name));
    }

    [Fact]
    public void Success_Throws_WhenUserNull()
    {
        Assert.Throws<ArgumentNullException>(() => AuthorityCredentialVerificationResult.Success(null!));
    }

    [Fact]
    public void Failure_SetsFailureCode()
    {
        var auditProperties = new[]
        {
            new AuthEventProperty { Name = "reason", Value = ClassifiedString.Public("lockout") }
        };

        var result = AuthorityCredentialVerificationResult.Failure(AuthorityCredentialFailureCode.LockedOut, "locked", TimeSpan.FromMinutes(5), auditProperties);

        Assert.False(result.Succeeded);
        Assert.Null(result.User);
        Assert.Equal(AuthorityCredentialFailureCode.LockedOut, result.FailureCode);
        Assert.Equal("locked", result.Message);
        Assert.Equal(TimeSpan.FromMinutes(5), result.RetryAfter);
        Assert.Collection(result.AuditProperties, property => Assert.Equal("reason", property.Name));
    }
}
