using Microsoft.AspNetCore.Authorization;

namespace ScadaLink.Security;

/// <summary>
/// Authorization requirement for site-scoped deployment operations.
/// </summary>
public class SiteScopeRequirement : IAuthorizationRequirement
{
    public string TargetSiteId { get; }

    public SiteScopeRequirement(string targetSiteId)
    {
        TargetSiteId = targetSiteId ?? throw new ArgumentNullException(nameof(targetSiteId));
    }
}

/// <summary>
/// Checks that a user with the Deployment role is permitted to operate on the target site.
/// Users with Deployment role and no SiteId claims are system-wide deployers.
/// Users with SiteId claims are only permitted on those specific sites.
/// </summary>
public class SiteScopeAuthorizationHandler : AuthorizationHandler<SiteScopeRequirement>
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context,
        SiteScopeRequirement requirement)
    {
        // Must have Deployment role
        var hasDeploymentRole = context.User.HasClaim(JwtTokenService.RoleClaimType, "Deployment");
        if (!hasDeploymentRole)
        {
            return Task.CompletedTask; // Fail — no Deployment role
        }

        var siteIdClaims = context.User.FindAll(JwtTokenService.SiteIdClaimType).ToList();

        if (siteIdClaims.Count == 0)
        {
            // No site scope restrictions — system-wide deployer
            context.Succeed(requirement);
        }
        else if (siteIdClaims.Any(c => c.Value == requirement.TargetSiteId))
        {
            // User is permitted on this specific site
            context.Succeed(requirement);
        }

        // Otherwise, silently fail (not authorized for this site)
        return Task.CompletedTask;
    }
}
