using ScadaLink.Commons.Interfaces.Repositories;

namespace ScadaLink.Security;

public class RoleMapper
{
    private readonly ISecurityRepository _securityRepository;

    public RoleMapper(ISecurityRepository securityRepository)
    {
        _securityRepository = securityRepository ?? throw new ArgumentNullException(nameof(securityRepository));
    }

    public async Task<RoleMappingResult> MapGroupsToRolesAsync(
        IReadOnlyList<string> ldapGroups,
        CancellationToken ct = default)
    {
        var allMappings = await _securityRepository.GetAllMappingsAsync(ct);

        var matchedRoles = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
        var permittedSiteIds = new HashSet<string>();
        var hasDeploymentRole = false;
        var hasDeploymentWithScopeRules = false;

        foreach (var mapping in allMappings)
        {
            // Match LDAP group names (case-insensitive)
            if (!ldapGroups.Any(g => g.Equals(mapping.LdapGroupName, StringComparison.OrdinalIgnoreCase)))
                continue;

            matchedRoles.Add(mapping.Role);

            if (mapping.Role.Equals("Deployment", StringComparison.OrdinalIgnoreCase))
            {
                hasDeploymentRole = true;

                // Check for site scope rules
                var scopeRules = await _securityRepository.GetScopeRulesForMappingAsync(mapping.Id, ct);
                if (scopeRules.Count > 0)
                {
                    hasDeploymentWithScopeRules = true;
                    foreach (var rule in scopeRules)
                    {
                        permittedSiteIds.Add(rule.SiteId.ToString());
                    }
                }
            }
        }

        // System-wide deployment: user has Deployment role but no site scope rules restrict them
        var isSystemWide = hasDeploymentRole && !hasDeploymentWithScopeRules;

        return new RoleMappingResult(
            matchedRoles.ToList(),
            permittedSiteIds.ToList(),
            isSystemWide);
    }
}
