using Microsoft.Extensions.Options;
using ZB.MOM.WW.Auth.Abstractions.Roles;
using ZB.MOM.WW.MxGateway.Server.Configuration;

namespace ZB.MOM.WW.MxGateway.Server.Dashboard;

/// <summary>
/// Shared-Auth <see cref="IGroupRoleMapper{TRole}"/> seam over the dashboard's
/// LDAP-group → role mapping. Roles are plain strings
/// (<see cref="DashboardRoles.Admin"/> / <see cref="DashboardRoles.Viewer"/>),
/// so <c>TRole</c> is <see cref="string"/>. The mapping rules (full-DN first,
/// leading-RDN fallback, case-insensitive) live in
/// <see cref="DashboardGroupRoleMapping"/>, shared with
/// <see cref="DashboardAuthenticator"/> so behaviour stays identical.
/// </summary>
/// <param name="options">Gateway options supplying the dashboard GroupToRole map.</param>
public sealed class DashboardGroupRoleMapper(IOptions<GatewayOptions> options)
    : IGroupRoleMapper<string>
{
    /// <summary>Maps the supplied dashboard LDAP group memberships to a dashboard role.</summary>
    /// <param name="groups">The user's directory group memberships.</param>
    /// <param name="ct">A token to request cancellation of the operation.</param>
    /// <returns>The dashboard roles granted; scope is unused and always <see langword="null"/>.</returns>
    public Task<GroupRoleMapping<string>> MapAsync(
        IReadOnlyList<string> groups,
        CancellationToken ct)
    {
        IReadOnlyList<string> roles = DashboardGroupRoleMapping.MapGroupsToRoles(
            groups,
            options.Value.Dashboard.GroupToRole);

        return Task.FromResult(new GroupRoleMapping<string>(roles, Scope: null));
    }
}
