"""Actions that do not support resource-level permissions.

These actions only accept ``Resource: "*"`` -- an SCP statement that restricts
Resource to a specific ARN will have no effect on these actions.  AWS silently
ignores the Resource element for them, which is a common source of SCP
authoring mistakes.

The set is curated from the AWS Service Authorization Reference for the most
commonly used services.  It is intentionally conservative: only actions that
are confirmed to be global (require ``*``) are included.

See also: https://docs.aws.amazon.com/service-authorization/latest/reference/
"""

from __future__ import annotations

# Actions that only support Resource: "*" (no resource-level permissions).
# Grouped by service prefix.  Keep alphabetical within each group.
GLOBAL_ACTIONS: frozenset[str] = frozenset({
    # IAM -- account-level operations
    "iam:CreateAccountAlias",
    "iam:GenerateCredentialReport",
    "iam:GetAccountAuthorizationDetails",
    "iam:GetAccountPasswordPolicy",
    "iam:GetAccountSummary",
    "iam:GetCredentialReport",
    "iam:ListAccountAliases",
    "iam:ListGroups",
    "iam:ListOpenIDConnectProviders",
    "iam:ListPolicies",
    "iam:ListRoles",
    "iam:ListSAMLProviders",
    "iam:ListServerCertificates",
    "iam:ListUsers",
    # S3 -- account-level
    "s3:CreateBucket",
    "s3:ListAllMyBuckets",
    # STS -- global operations
    "sts:DecodeAuthorizationMessage",
    "sts:GetAccessKeyInfo",
    "sts:GetCallerIdentity",
    "sts:GetSessionToken",
    # EC2 -- Describe operations that don't support resource-level permissions
    "ec2:DescribeAddresses",
    "ec2:DescribeAvailabilityZones",
    "ec2:DescribeImages",
    "ec2:DescribeInstances",
    "ec2:DescribeKeyPairs",
    "ec2:DescribeNetworkInterfaces",
    "ec2:DescribeRegions",
    "ec2:DescribeRouteTables",
    "ec2:DescribeSecurityGroups",
    "ec2:DescribeSnapshots",
    "ec2:DescribeSubnets",
    "ec2:DescribeVolumes",
    "ec2:DescribeVpcs",
    # CloudWatch
    "cloudwatch:GetMetricData",
    "cloudwatch:ListDashboards",
    "cloudwatch:ListMetrics",
    # Lambda
    "lambda:GetAccountSettings",
    "lambda:ListFunctions",
    "lambda:ListLayers",
    # DynamoDB
    "dynamodb:DescribeEndpoints",
    "dynamodb:DescribeLimits",
    "dynamodb:ListTables",
    # SNS
    "sns:ListSubscriptions",
    "sns:ListTopics",
    # SQS
    "sqs:ListQueues",
    # KMS
    "kms:ListAliases",
    "kms:ListKeys",
    # Organizations
    "organizations:DescribeOrganization",
    "organizations:ListAccounts",
    "organizations:ListRoots",
    # CloudTrail
    "cloudtrail:DescribeTrails",
    "cloudtrail:GetTrailStatus",
    "cloudtrail:LookupEvents",
    # CloudFormation
    "cloudformation:ListExports",
    "cloudformation:ListStacks",
})

# Lowercase lookup set for case-insensitive matching
_GLOBAL_ACTIONS_LOWER: frozenset[str] = frozenset(
    a.lower() for a in GLOBAL_ACTIONS
)


def is_global_action(action: str) -> bool:
    """Check whether an action does not support resource-level permissions.

    Args:
        action: Fully-qualified action string (e.g. ``iam:ListUsers``).

    Returns:
        True if the action is known to only accept ``Resource: "*"``.
    """
    return action.lower() in _GLOBAL_ACTIONS_LOWER
