using Shouldly;
using Xunit;

namespace ZB.MOM.WW.OtOpcUa.Cluster.Tests;

public sealed class RoleParserTests
{
    /// <summary>Verifies that empty input yields an empty array.</summary>
    /// <param name="raw">The raw input string to test (null, empty, or whitespace).</param>
    [Theory]
    [InlineData(null)]
    [InlineData("")]
    [InlineData("   ")]
    public void Empty_input_yields_empty_array(string? raw)
    {
        RoleParser.Parse(raw).ShouldBeEmpty();
    }

    /// <summary>Verifies that a single role 'admin' is parsed correctly.</summary>
    [Fact]
    public void Single_role_admin()
    {
        RoleParser.Parse("admin").ShouldBe(new[] { "admin" });
    }

    /// <summary>Verifies that two roles separated by comma are parsed correctly.</summary>
    [Fact]
    public void Two_roles_csv()
    {
        RoleParser.Parse("admin,driver").ShouldBe(new[] { "admin", "driver" });
    }

    /// <summary>Verifies that parser tolerates surrounding whitespace.</summary>
    [Fact]
    public void Whitespace_tolerant()
    {
        RoleParser.Parse(" admin , driver ").ShouldBe(new[] { "admin", "driver" });
    }

    /// <summary>Verifies that parser is case-insensitive and normalizes to lowercase.</summary>
    [Fact]
    public void Case_insensitive_normalizes_to_lower()
    {
        RoleParser.Parse("ADMIN,Driver").ShouldBe(new[] { "admin", "driver" });
    }

    /// <summary>Verifies that duplicate roles are removed.</summary>
    [Fact]
    public void Duplicate_roles_deduped()
    {
        RoleParser.Parse("admin,admin,driver").ShouldBe(new[] { "admin", "driver" });
    }

    /// <summary>Verifies that parser throws for unknown roles.</summary>
    [Fact]
    public void Unknown_role_throws()
    {
        Should.Throw<ArgumentException>(() => RoleParser.Parse("admin,master"));
    }
}
