build.ps1

[CmdletBinding()]
param(
    [switch]$SkipAnalyzer,
    [switch]$SkipTests,
    [switch]$Validate
)

$ErrorActionPreference = 'Stop'

Write-Output "[BUILD] === WinHarden Build ==="

# PSScriptAnalyzer - Inline Settings (removed - use external config file)
if (-not $SkipAnalyzer) {
    Write-Output "`n[PSScriptAnalyzer] Linting..."

    $analyzerSettings = Join-Path $PSScriptRoot 'PSScriptAnalyzerSettings.psd1'

    $analyzerPaths = @('./functions', './scripts')
    $analyzerResults = @()

    foreach ($path in $analyzerPaths) {
        if (Test-Path $path) {
            $results = Invoke-ScriptAnalyzer -Path $path -Settings $analyzerSettings -Recurse
            $analyzerResults += $results
        }
    }

    if ($analyzerResults) {
        Write-Output "PSScriptAnalyzer found $(($analyzerResults | Measure-Object).Count) issues:"
        $analyzerResults | Format-Table -AutoSize
        throw "PSScriptAnalyzer validation failed"
    }

    Write-Output "[PSScriptAnalyzer] PASSED"
}

# Pester Tests - Code Coverage (Pester 5.x)
if (-not $SkipTests) {
    Write-Output "`n[Pester] Running tests..."

    $pesterConfig = New-PesterConfiguration
    $pesterConfig.Run.Path = './tests'
    $pesterConfig.Run.PassThru = $true
    $pesterConfig.Output.Verbosity = 'Detailed'

    if (-not $Validate) {
        $pesterConfig.CodeCoverage.Enabled = $true
        $pesterConfig.CodeCoverage.Path = './functions'
    }

    $testResults = Invoke-Pester -Configuration $pesterConfig

    if ($testResults.FailedCount -gt 0) {
        Write-Output "`nTests FAILED: $($testResults.FailedCount) failure(s)"
        throw "Pester tests failed"
    }

    # Code Coverage Check (Pester 5.x format) - ADR-003 Enforcement
    if (-not $Validate -and $testResults.CodeCoverage) {
        Write-Output "`n[CodeCoverage] Analyzing code coverage..."

        $coverageData = $testResults.CodeCoverage
        if ($coverageData -and $coverageData.Count -gt 0) {
            $totalLines = $coverageData.Count
            $hitLines = @($coverageData | Where-Object { $_.Hit -eq $true }).Count
            $missedLines = $totalLines - $hitLines
            $coveragePercent = [math]::Round(($hitLines / $totalLines) * 100, 2)

            Write-Output " Total lines analyzed: $totalLines"
            Write-Output " Lines hit: $hitLines"
            Write-Output " Lines missed: $missedLines"
            Write-Output " Overall Coverage: $coveragePercent%"

            # Enforce 95% minimum coverage (ADR-003 requirement)
            $minCoverage = 95
            if ($coveragePercent -lt $minCoverage) {
                Write-Output "`n[CodeCoverage] ERROR: Coverage ($coveragePercent%) is BELOW minimum ($minCoverage%)"
                Write-Output " Required by: ADR-003 (Testing Framework requirement)"
                Write-Output " Status: COVERAGE THRESHOLD NOT MET"

                # Show per-file coverage analysis
                Write-Output "`n Per-File Coverage Analysis:"
                $fileGroups = $coverageData | Group-Object -Property File
                foreach ($fileGroup in $fileGroups) {
                    $filePath = $fileGroup.Name
                    $fileName = Split-Path $filePath -Leaf
                    $fileTotalLines = $fileGroup.Count
                    $fileHitLines = @($fileGroup.Group | Where-Object { $_.Hit -eq $true }).Count
                    $fileCoveragePercent = [math]::Round(($fileHitLines / $fileTotalLines) * 100, 2)

                    $status = if ($fileCoveragePercent -lt $minCoverage) {
                        "[LOW]"
                    }
                    else {
                        "[OK]"
                    }
                    Write-Output " $status $fileName : $fileCoveragePercent% ($fileHitLines/$fileTotalLines lines)"
                }

                throw "[ADR-003] Code coverage check failed: $coveragePercent% < $minCoverage% minimum"
            }
            else {
                Write-Output "`n[OK] CodeCoverage PASSED - Coverage $coveragePercent% meets $minCoverage% minimum (ADR-003)"
            }
        }
        else {
            Write-Output " Warning: Coverage data not available (may require Pester 5.7+)"
        }
    }

    Write-Output "[Pester] PASSED"
}

Write-Output "`n=== Build Successful ==="
exit 0