internal static string ResourceId()

in src/PSRule.Rules.Azure/Common/ResourceHelper.cs [342:423]


    internal static string ResourceId(string? scopeTenant, string? scopeManagementGroup, string? scopeSubscriptionId, string? scopeResourceGroup, string[]? resourceType, string[]? resourceName, int depth = int.MaxValue)
    {
        var resourceTypeLength = resourceType?.Length ?? 0;
        var nameLength = resourceName?.Length ?? 0;
        if (resourceTypeLength != nameLength)
            throw new TemplateFunctionException(nameof(resourceType), FunctionErrorType.MismatchingResourceSegments, PSRuleResources.MismatchingResourceSegments);

        // Coalesce depth.
        var actualDepth = ResourceIdDepth(scopeTenant, scopeManagementGroup, scopeSubscriptionId, scopeResourceGroup, resourceType, resourceName);
        depth = depth < 0 ? actualDepth + depth : depth > actualDepth ? actualDepth : depth;

        var parts = scopeTenant == SLASH ? 1 : scopeSubscriptionId != null ? 4 : scopeManagementGroup != null ? 8 : 0;
        parts += scopeResourceGroup != null ? 4 : 0;
        parts += depth >= resourceTypeLength ? resourceTypeLength * 4 : depth * 4;

        // Add additional provider segments.
        for (var p = 0; resourceType != null && p < resourceType.Length; p++)
        {
            if (resourceType[p].Contains(DOT))
                parts += 2;
        }

        var result = new string[parts];
        var i = 0;
        var j = 0;
        var currentDepth = 0;

        if (scopeTenant == null && scopeManagementGroup != null && depth >= 1)
        {
            result[i++] = SLASH;
            result[i++] = PROVIDERS;
            result[i++] = SLASH;
            result[i++] = PROVIDER_MICROSOFT_MANAGEMENT;
            result[i++] = SLASH;
            result[i++] = MANAGEMENT_GROUPS;
            result[i++] = SLASH;
            result[i++] = scopeManagementGroup;
            currentDepth++;
        }
        else if (scopeTenant == null && scopeSubscriptionId != null && depth >= 1)
        {
            result[i++] = SLASH;
            result[i++] = SUBSCRIPTIONS;
            result[i++] = SLASH;
            result[i++] = scopeSubscriptionId;
            currentDepth++;

            if (scopeResourceGroup != null && depth >= 2)
            {
                result[i++] = SLASH;
                result[i++] = RESOURCE_GROUPS;
                result[i++] = SLASH;
                result[i++] = scopeResourceGroup;
                currentDepth++;
            }
        }

        // Handle resource type and name.
        if (depth > currentDepth && resourceType != null && resourceName != null && resourceTypeLength > 0)
        {
            while (i < result.Length && depth > currentDepth && j < resourceTypeLength)
            {
                // If a resource provider is included providers segment.
                if (resourceType[j].Contains(DOT))
                {
                    result[i++] = SLASH;
                    result[i++] = PROVIDERS;
                }

                // Don't increment when providers is already in the type segment.
                if (!string.Equals(resourceType[j], PROVIDERS, StringComparison.OrdinalIgnoreCase))
                    currentDepth++;

                result[i++] = SLASH;
                result[i++] = resourceType[j];
                result[i++] = SLASH;
                result[i++] = resourceName[j++];
            }
        }

        return scopeTenant != null && i == 0 ? SLASH : string.Concat(result);
    }