Private/New-PstGeneratedCode.ps1

function New-PstGeneratedCode {
    <#
    .SYNOPSIS
        Generates complete PowerShell code based on configuration and complexity level.

    .DESCRIPTION
        The New-PstGeneratedCode function is the main orchestrator that assembles all
        component builder functions to generate complete PowerShell functions, scripts,
        or modules. It accepts a configuration object and produces properly formatted,
        working PowerShell code based on the specified complexity level.

    .PARAMETER FunctionName
        The name of the function, script, or module to generate.

    .PARAMETER Type
        The type of code to generate. Valid values: Function, Script, Module.

    .PARAMETER Complexity
        The complexity level of the generated code. Valid values: Basic, Standard, Advanced.

    .PARAMETER Parameters
        Array of parameter definitions. Each can be a string (parameter name) or hashtable
        with Name, Type, Mandatory, Pipeline, ValidationSet, etc.

    .PARAMETER Synopsis
        Brief description for the .SYNOPSIS section of comment-based help.

    .PARAMETER Description
        Detailed description for the .DESCRIPTION section of comment-based help.

    .PARAMETER Examples
        Array of usage examples for the .EXAMPLE sections.

    .PARAMETER Notes
        Additional notes for the .NOTES section.

    .PARAMETER Author
        Author name for the .NOTES section. Defaults to "numidia".

    .EXAMPLE
        $params = @{
            FunctionName = "Get-UserData"
            Type = "Function"
            Complexity = "Standard"
            Parameters = @("UserId", "IncludeDetails")
            Synopsis = "Retrieves user data from the system"
        }
        New-PstGeneratedCode @params

        Generates a Standard complexity function with two string parameters.

    .EXAMPLE
        $params = @{
            FunctionName = "Process-Items"
            Type = "Function"
            Complexity = "Advanced"
            Parameters = @(
                @{ Name = "InputObject"; Type = "object[]"; Pipeline = $true; Mandatory = $true }
                @{ Name = "BatchSize"; Type = "int"; DefaultValue = 100 }
            )
            Synopsis = "Processes items in batches"
        }
        New-PstGeneratedCode @params

        Generates an Advanced complexity function with typed parameters.

    .NOTES
        Version: 1.0
        Author: numidia
        Creation Date: 2025-12-03
        Purpose/Change: Initial implementation for Issue #9
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$FunctionName,

        [Parameter(Mandatory = $true)]
        [ValidateSet('Function', 'Script', 'Module')]
        [string]$Type,

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

        [Parameter(Mandatory = $false)]
        [object[]]$Parameters = @(),

        [Parameter(Mandatory = $false)]
        [string]$Synopsis,

        [Parameter(Mandatory = $false)]
        [string]$Description,

        [Parameter(Mandatory = $false)]
        [string[]]$Examples,

        [Parameter(Mandatory = $false)]
        [string]$Notes,

        [Parameter(Mandatory = $false)]
        [string]$Author = 'numidia'
    )

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

        # Validate function name has approved verb if Type is Function
        if ($Type -eq 'Function') {
            $verb = ($FunctionName -split '-')[0]
            if (-not (Get-PstApprovedVerb -Verb $verb)) {
                Write-Warning "Verb '$verb' is not an approved PowerShell verb. Consider using an approved verb."
            }
        }

        # Initialize string builder for efficient code assembly
        $codeBuilder = [System.Text.StringBuilder]::new()
    }

    process {
        try {
            # Normalize parameters to standard format (wrap in @() to ensure array)
            $normalizedParams = @()
            if ($Parameters.Count -gt 0) {
                $normalizedParams = @(ConvertTo-PstParameterDefinition -ParameterInput $Parameters)
            }

            # Get complexity features to determine structure
            $features = Get-PstComplexityFeatures -Complexity $Complexity -Type $Type

            # Handle different types
            if ($Type -eq 'Script') {
                # Scripts have different structure - no function wrapper
                $generatedCode = New-PstScriptContent `
                    -ScriptName $FunctionName `
                    -Complexity $Complexity `
                    -Parameters $normalizedParams `
                    -Synopsis $Synopsis `
                    -Description $Description `
                    -Examples $Examples `
                    -Notes $Notes `
                    -Author $Author

                Write-Output $generatedCode
                return
            }

            # For Functions, continue with function-style generation
            # Build help description (New-PstCommentBasedHelp uses Description for SYNOPSIS)
            $helpDescription = if ($Synopsis) { $Synopsis } elseif ($Description) { $Description } else { "Brief description of $FunctionName" }

            # Build examples array
            $helpExamples = if ($Examples) { $Examples } else { @("$FunctionName -Parameter Value") }

            # Generate comment-based help
            $help = New-PstCommentBasedHelp `
                -FunctionName $FunctionName `
                -Complexity $Complexity `
                -Parameters $normalizedParams `
                -Description $helpDescription `
                -Examples $helpExamples

            [void]$codeBuilder.AppendLine($help)

            # Generate function signature
            $signature = New-PstFunctionSignature -FunctionName $FunctionName -Complexity $Complexity
            [void]$codeBuilder.AppendLine($signature)

            # Generate parameter block if we have parameters or complexity requires it
            if ($normalizedParams.Count -gt 0 -or $Complexity -in @('Standard', 'Advanced')) {
                $paramBlock = New-PstParameterBlock -Parameters $normalizedParams -Complexity $Complexity
                [void]$codeBuilder.AppendLine($paramBlock)
                [void]$codeBuilder.AppendLine()
            }

            # Generate begin block if supported (Function type)
            if ($features.Structure.ContainsKey('BeginBlock') -and $features.Structure.BeginBlock) {
                $beginBlock = New-PstBeginBlock -Complexity $Complexity -FunctionName $FunctionName
                [void]$codeBuilder.AppendLine($beginBlock)
                [void]$codeBuilder.AppendLine()
            }

            # Generate process block
            $pipelineParams = @($normalizedParams | Where-Object { $_.Pipeline -eq $true })
            $processBlock = New-PstProcessBlock `
                -Complexity $Complexity `
                -FunctionName $FunctionName `
                -HasShouldProcess ($pipelineParams.Count -gt 0)

            [void]$codeBuilder.AppendLine($processBlock)

            # Generate end block if supported (Function type)
            if ($features.Structure.ContainsKey('EndBlock') -and $features.Structure.EndBlock) {
                [void]$codeBuilder.AppendLine()
                $endBlock = New-PstEndBlock -Complexity $Complexity -FunctionName $FunctionName
                [void]$codeBuilder.AppendLine($endBlock)
            }

            # Close function
            [void]$codeBuilder.AppendLine('}')

            # Return generated code
            $generatedCode = $codeBuilder.ToString()

            # Basic syntax validation - check for balanced braces
            $openBraces = ($generatedCode.ToCharArray() | Where-Object { $_ -eq '{' }).Count
            $closeBraces = ($generatedCode.ToCharArray() | Where-Object { $_ -eq '}' }).Count

            if ($openBraces -ne $closeBraces) {
                Write-Warning "Generated code may have unbalanced braces: $openBraces open, $closeBraces close"
            }

            Write-Output $generatedCode
        }
        catch {
            $PSCmdlet.ThrowTerminatingError($_)
        }
    }

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