Public/Test-LocalRepository.ps1

function Test-LocalRepository {
    <#
    .SYNOPSIS
        Validate a local repository structure and contents.
 
    .DESCRIPTION
        Performs comprehensive validation of a local repository, checking for:
        - Directory existence and permissions
        - Package file integrity
        - Duplicate packages
        - Naming conventions
        - File corruption
 
    .PARAMETER Path
        Path to the local repository. Defaults to C:\LocalNuGetRepo.
 
    .PARAMETER Fix
        Attempt to fix common issues automatically.
 
    .PARAMETER Detailed
        Show detailed information for each package.
 
    .EXAMPLE
        Test-LocalRepository
         
        Validates the default repository and shows summary.
 
    .EXAMPLE
        Test-LocalRepository -Path "C:\MyRepo" -Fix -Detailed
         
        Validates custom repository, fixes issues, and shows detailed output.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Position = 0)]
        [string]$Path = $script:DefaultRepositoryPath,
        
        [Parameter()]
        [switch]$Fix,
        
        [Parameter()]
        [switch]$Detailed
    )

    try {
        Write-Host "Validating local repository: $Path" -ForegroundColor Cyan
        Write-Host "=================================" -ForegroundColor Cyan
        
        $issues = @()
        $warnings = @()
        $validPackages = @()
        $invalidPackages = @()
        
        # Check if repository directory exists
        if (-not (Test-Path -Path $Path -PathType Container)) {
            $issues += "Repository directory does not exist: $Path"
            
            if ($Fix) {
                try {
                    New-Item -Path $Path -ItemType Directory -Force | Out-Null
                    Write-Host " [FIXED] Created repository directory" -ForegroundColor Green
                } catch {
                    $issues += "Failed to create repository directory: $($_.Exception.Message)"
                }
            }
        } else {
            Write-Host " [OK] Repository directory exists" -ForegroundColor Green
        }
        
        # Check directory permissions
        try {
            $testFile = Join-Path -Path $Path -ChildPath "test_write_$(Get-Random).tmp"
            "test" | Out-File -FilePath $testFile -Force
            Remove-Item -Path $testFile -Force
            Write-Host " [OK] Directory is writable" -ForegroundColor Green
        } catch {
            $issues += "Repository directory is not writable: $($_.Exception.Message)"
        }
        
        # Find and validate packages
        $nupkgFiles = Get-ChildItem -Path $Path -Filter "*.nupkg" -File -ErrorAction SilentlyContinue
        
        if (-not $nupkgFiles) {
            $warnings += "No NuPkg files found in repository"
            Write-Host " [WARN] No packages found" -ForegroundColor Yellow
        } else {
            Write-Host " [INFO] Found $($nupkgFiles.Count) package files" -ForegroundColor Gray
            
            # Validate each package
            foreach ($file in $nupkgFiles) {
                Write-Verbose "Validating package: $($file.Name)"
                
                $pkgValidation = @{
                    FileName = $file.Name
                    FilePath = $file.FullName
                    Size = $file.Length
                    Valid = $false
                    Issues = @()
                    ParsedInfo = $null
                }
                
                # Try to parse package info
                $pkgInfo = Get-NuPkgInfo -FilePath $file.FullName
                if ($pkgInfo) {
                    $pkgValidation.Valid = $true
                    $pkgValidation.ParsedInfo = $pkgInfo
                    $validPackages += $pkgValidation
                    
                    if ($Detailed) {
                        Write-Host " [OK] $($pkgInfo.Name) v$($pkgInfo.VersionString) ($($pkgInfo.Size) MB)" -ForegroundColor Green
                    }
                } else {
                    $pkgValidation.Issues += "Could not parse package name/version from filename"
                    $invalidPackages += $pkgValidation
                    
                    if ($Detailed) {
                        Write-Host " [ERROR] $($file.Name) - Invalid filename format" -ForegroundColor Red
                    }
                }
                
                # Check file integrity (basic ZIP validation)
                try {
                    Add-Type -AssemblyName System.IO.Compression.FileSystem
                    $zip = [System.IO.Compression.ZipFile]::OpenRead($file.FullName)
                    $entryCount = $zip.Entries.Count
                    $zip.Dispose()
                    
                    if ($entryCount -eq 0) {
                        $pkgValidation.Issues += "Package file appears to be empty"
                        if ($pkgValidation.Valid) {
                            $validPackages = $validPackages | Where-Object { $_.FileName -ne $file.Name }
                            $invalidPackages += $pkgValidation
                        }
                    }
                } catch {
                    $pkgValidation.Issues += "Package file is corrupted or not a valid ZIP: $($_.Exception.Message)"
                    if ($pkgValidation.Valid) {
                        $validPackages = $validPackages | Where-Object { $_.FileName -ne $file.Name }
                        $invalidPackages += $pkgValidation
                    }
                }
            }
            
            # Check for duplicate packages (same name, different versions)
            if ($validPackages.Count -gt 0) {
                $packageGroups = $validPackages | Group-Object { $_.ParsedInfo.Name }
                $duplicateGroups = $packageGroups | Where-Object { $_.Count -gt 1 }
                
                if ($duplicateGroups) {
                    Write-Host " [INFO] Found packages with multiple versions:" -ForegroundColor Gray
                    foreach ($group in $duplicateGroups) {
                        $versions = $group.Group.ParsedInfo.VersionString | Sort-Object
                        Write-Host " - $($group.Name): $($versions -join ', ')" -ForegroundColor Gray
                    }
                }
            }
        }
        
        # Generate validation report
        Write-Host "`nValidation Results:" -ForegroundColor Green
        Write-Host "==================" -ForegroundColor Green
        
        Write-Host "Repository Path: $Path" -ForegroundColor White
        Write-Host "Total Files: $($nupkgFiles.Count)" -ForegroundColor White
        Write-Host "Valid Packages: $($validPackages.Count)" -ForegroundColor Green
        Write-Host "Invalid Packages: $($invalidPackages.Count)" -ForegroundColor Red
        Write-Host "Issues: $($issues.Count)" -ForegroundColor $(if ($issues.Count -eq 0) { 'Green' } else { 'Red' })
        Write-Host "Warnings: $($warnings.Count)" -ForegroundColor $(if ($warnings.Count -eq 0) { 'Green' } else { 'Yellow' })
        
        # Show issues
        if ($issues.Count -gt 0) {
            Write-Host "`nIssues Found:" -ForegroundColor Red
            foreach ($issue in $issues) {
                Write-Host " - $issue" -ForegroundColor Red
            }
        }
        
        # Show warnings
        if ($warnings.Count -gt 0) {
            Write-Host "`nWarnings:" -ForegroundColor Yellow
            foreach ($warning in $warnings) {
                Write-Host " - $warning" -ForegroundColor Yellow
            }
        }
        
        # Show invalid packages
        if ($invalidPackages.Count -gt 0) {
            Write-Host "`nInvalid Packages:" -ForegroundColor Red
            foreach ($pkg in $invalidPackages) {
                Write-Host " - $($pkg.FileName)" -ForegroundColor Red
                foreach ($issue in $pkg.Issues) {
                    Write-Host " * $issue" -ForegroundColor Red
                }
                
                if ($Fix) {
                    $removeInvalid = Read-Host " Remove invalid package $($pkg.FileName)? (y/N)"
                    if ($removeInvalid -in @('y', 'Y', 'yes', 'Yes', 'YES')) {
                        try {
                            Remove-Item -Path $pkg.FilePath -Force
                            Write-Host " [FIXED] Removed invalid package" -ForegroundColor Green
                        } catch {
                            Write-Warning " Failed to remove invalid package: $($_.Exception.Message)"
                        }
                    }
                }
            }
        }
        
        # Overall status
        $overallStatus = if ($issues.Count -eq 0 -and $invalidPackages.Count -eq 0) {
            "HEALTHY"
        } elseif ($issues.Count -eq 0) {
            "WARNING"
        } else {
            "ERROR"
        }
        
        Write-Host "`nRepository Status: " -NoNewline
        switch ($overallStatus) {
            "HEALTHY" { Write-Host "HEALTHY" -ForegroundColor Green }
            "WARNING" { Write-Host "WARNING" -ForegroundColor Yellow }
            "ERROR" { Write-Host "ERROR" -ForegroundColor Red }
        }
        
        # Return validation object
        return [PSCustomObject]@{
            RepositoryPath = $Path
            Status = $overallStatus
            TotalFiles = $nupkgFiles.Count
            ValidPackages = $validPackages.Count
            InvalidPackages = $invalidPackages.Count
            Issues = $issues
            Warnings = $warnings
            InvalidPackageDetails = $invalidPackages
        }
        
    } catch {
        Write-Error "Failed to validate repository: $($_.Exception.Message)"
    }
}