Private/New-PstParameterBlock.ps1

function New-PstParameterBlock {
    <#
    .SYNOPSIS
        Generates PowerShell parameter block code.

    .DESCRIPTION
        Creates a formatted param() block with appropriate attributes,
        validation, and features based on complexity level.

    .PARAMETER Parameters
        Array of parameter hashtables (normalized format).

    .PARAMETER Complexity
        The complexity level: Basic, Standard, or Advanced.

    .EXAMPLE
        New-PstParameterBlock -Parameters @(@{Name="UserId"; Type="string"; Mandatory=$true}) -Complexity Standard
        Generates a Standard complexity parameter block.

    .NOTES
        Version: 1.0
        Author: numidia
        Creation Date: 2025-12-01
        Purpose: Generate parameter blocks for functions
    #>

    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory = $false)]
        [AllowEmptyCollection()]
        [hashtable[]]$Parameters = @(),

        [Parameter(Mandatory = $true)]
        [ValidateSet('Basic', 'Standard', 'Advanced')]
        [string]$Complexity
    )

    begin {
        Write-Debug "Begin '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'"
    }

    process {
        try {
            # Ensure Parameters is an array
            $params = @($Parameters)

            if ($params.Count -eq 0) {
                Write-Verbose "No parameters specified, generating empty param block"
                return " param()"
            }

            $features = Get-PstComplexityFeatures -Complexity $Complexity -Type Function
            $sb = [System.Text.StringBuilder]::new()

            [void]$sb.AppendLine(" param(")

            for ($i = 0; $i -lt $params.Count; $i++) {
                $param = $params[$i]
                $isLast = ($i -eq ($params.Count - 1))

                # Build Parameter attribute
                $paramAttributes = [System.Collections.ArrayList]::new()

                # Get values with null-safe access
                $isMandatory = if ($param.ContainsKey('Mandatory')) { $param.Mandatory } else { $false }
                $position = if ($param.ContainsKey('Position')) { $param.Position } else { $null }
                $pipeline = if ($param.ContainsKey('Pipeline')) { $param.Pipeline } else { $false }
                $helpMessage = if ($param.ContainsKey('HelpMessage')) { $param.HelpMessage } else { '' }
                $validation = if ($param.ContainsKey('Validation')) { $param.Validation } else { @() }
                $validationSet = if ($param.ContainsKey('ValidationSet')) { $param.ValidationSet } else { $null }
                $paramType = if ($param.ContainsKey('Type')) { $param.Type } else { 'string' }
                $defaultValue = if ($param.ContainsKey('DefaultValue')) { $param.DefaultValue } else { $null }

                [void]$paramAttributes.Add("Mandatory = `$$($isMandatory.ToString().ToLower())")

                # Add position for Standard and Advanced
                if ($features.Parameters.SupportsPosition -and $null -ne $position) {
                    [void]$paramAttributes.Add("Position = $position")
                }

                # Add pipeline support for Standard and Advanced
                if ($features.Parameters.SupportsPipeline -and $pipeline) {
                    [void]$paramAttributes.Add("ValueFromPipeline = `$true")
                    [void]$paramAttributes.Add("ValueFromPipelineByPropertyName = `$true")
                }

                # Add help message for Standard and Advanced
                if ($features.Parameters.SupportsHelpMessages -and $helpMessage) {
                    [void]$paramAttributes.Add("HelpMessage = '$helpMessage'")
                }

                # Write Parameter attribute
                [void]$sb.AppendLine(" [Parameter($($paramAttributes -join ', '))]")

                # Add validation attributes
                $validationArray = @($validation)
                if ($validationArray.Count -gt 0) {
                    foreach ($val in $validationArray) {
                        # Check if validation is allowed at this complexity level
                        if ($features.Parameters.ValidateAttributes -contains $val) {
                            [void]$sb.AppendLine(" [$val()]")
                        }
                    }
                }

                # Add ValidationSet if specified (Standard and Advanced)
                if ($null -ne $validationSet -and $validationSet.Count -gt 0) {
                    if ($features.Parameters.ValidateAttributes -contains 'ValidateSet') {
                        $setValues = ($validationSet | ForEach-Object { "'$_'" }) -join ', '
                        [void]$sb.AppendLine(" [ValidateSet($setValues)]")
                    }
                }

                # Add type and name
                [void]$sb.Append(" [$paramType]`$$($param.Name)")

                # Add default value if specified
                if ($null -ne $defaultValue) {
                    if ($paramType -eq 'string') {
                        [void]$sb.Append(" = '$defaultValue'")
                    }
                    elseif ($paramType -eq 'bool') {
                        [void]$sb.Append(" = `$$defaultValue")
                    }
                    else {
                        [void]$sb.Append(" = $defaultValue")
                    }
                }

                # Add comma if not last parameter
                if (-not $isLast) {
                    [void]$sb.AppendLine(",")
                }
                else {
                    [void]$sb.AppendLine()
                }

                # Add blank line between parameters for readability (Standard/Advanced)
                if (-not $isLast -and $Complexity -in @('Standard', 'Advanced')) {
                    [void]$sb.AppendLine()
                }
            }

            [void]$sb.Append(" )")

            Write-Verbose "Generated $Complexity parameter block with $($Parameters.Count) parameter(s)"
            return $sb.ToString()
        }
        catch {
            Write-Error "Failed to generate parameter block: $($_.Exception.Message)"
            $PSCmdlet.ThrowTerminatingError($_)
        }
    }

    end {
        Write-Debug "End '$($MyInvocation.MyCommand.Name)' at '$(Get-Date)'"
    }
}