using ZB.MOM.WW.Auth.Ldap.Internal;

public class LdapEscapingTests {
    [Theory]
    [InlineData("a*b", @"a\2ab")]
    [InlineData("a(b)", @"a\28b\29")]
    [InlineData(@"a\b", @"a\5cb")]
    public void Filter_EscapesMetacharacters(string raw, string expected)
        => Assert.Equal(expected, LdapEscaping.Filter(raw));

    [Fact]
    public void Filter_EscapesNul()
        => Assert.Equal(@"a\00b", LdapEscaping.Filter("a\0b"));

    [Fact]
    public void Dn_EscapesSpecialChars()
        => Assert.Equal(@"\#cn\,test", LdapEscaping.Dn("#cn,test"));

    // M2: each RFC 4514 special char is backslash-escaped, plus leading/trailing space.
    [Theory]
    [InlineData("a,b", @"a\,b")]
    [InlineData("a+b", @"a\+b")]
    [InlineData("a\"b", "a\\\"b")]
    [InlineData(@"a\b", @"a\\b")]
    [InlineData("a<b", @"a\<b")]
    [InlineData("a>b", @"a\>b")]
    [InlineData("a;b", @"a\;b")]
    [InlineData(" ab", @"\ ab")]
    [InlineData("ab ", @"ab\ ")]
    public void Dn_EscapesEachSpecialChar(string raw, string expected)
        => Assert.Equal(expected, LdapEscaping.Dn(raw));

    // C1: RFC 4514 escape-aware first-RDN-value extraction.
    [Theory]
    [InlineData("cn=Engineers,ou=g,dc=x", "Engineers")]          // simple case still works
    [InlineData(@"cn=Eng\,ineers,ou=g,dc=x", "Eng,ineers")]      // single-char escaped comma
    [InlineData(@"cn=A\2cB,dc=x", "A,B")]                         // hex-escaped comma \2c
    [InlineData(@"cn=A\5cB,dc=x", @"A\B")]                        // hex-escaped backslash \5c
    public void FirstRdnValue_IsEscapeAware(string dn, string expected)
        => Assert.Equal(expected, LdapEscaping.FirstRdnValue(dn));
}
