using ZB.MOM.WW.Auth.ApiKeys;

namespace ZB.MOM.WW.Auth.ApiKeys.Tests;

public class ApiKeySecretGeneratorTests
{
    [Fact]
    public void NewSecret_ReturnsNonEmpty()
    {
        var secret = ApiKeySecretGenerator.NewSecret();

        Assert.NotEmpty(secret);
    }

    [Fact]
    public void NewSecret_TwoCallsDiffer()
    {
        var first = ApiKeySecretGenerator.NewSecret();
        var second = ApiKeySecretGenerator.NewSecret();

        Assert.NotEqual(first, second);
    }

    [Fact]
    public void NewSecret_DecodesToThirtyTwoBytes()
    {
        var secret = ApiKeySecretGenerator.NewSecret();

        // Restore URL-safe base64 to standard before decoding
        string standard = secret.Replace('-', '+').Replace('_', '/');
        // Add padding if needed
        int pad = standard.Length % 4;
        if (pad == 2) standard += "==";
        else if (pad == 3) standard += "=";

        byte[] bytes = Convert.FromBase64String(standard);

        Assert.Equal(32, bytes.Length);
    }

    [Fact]
    public void NewSecret_IsUrlSafe_NoPlus()
    {
        // Run many iterations to make collisions with '+' unlikely to be missed
        for (int i = 0; i < 200; i++)
        {
            Assert.DoesNotContain('+', ApiKeySecretGenerator.NewSecret());
        }
    }

    [Fact]
    public void NewSecret_IsUrlSafe_NoSlash()
    {
        for (int i = 0; i < 200; i++)
        {
            Assert.DoesNotContain('/', ApiKeySecretGenerator.NewSecret());
        }
    }

    [Fact]
    public void NewSecret_IsUrlSafe_NoPaddingEquals()
    {
        for (int i = 0; i < 200; i++)
        {
            Assert.DoesNotContain('=', ApiKeySecretGenerator.NewSecret());
        }
    }
}
