Private/GitRepositoryAnalysis.ps1

# Git Repository Analysis Functions
# Enhanced for module integration and professional use

function Get-CommitHistory {
    <#
    .SYNOPSIS
    Retrieves git commit history with enhanced metadata.
     
    .DESCRIPTION
    Extracts commit information including hash, message, author, and date
    with proper error handling and validation for AI analysis.
     
    .PARAMETER Since
    Time range for commits (default: "30 days ago")
     
    .PARAMETER Repository
    Path to git repository (default: current directory)
    #>

    
    [CmdletBinding()]
    param(
        [string]$Since = "30 days ago",
        [string]$Repository = (Get-Location)
    )
    
    # Validate git repository
    if (-not (Test-Path (Join-Path $Repository ".git"))) {
        throw "Not a git repository: $Repository"
    }
    
    # Change to repository directory
    $currentLocation = Get-Location
    try {
        Set-Location $Repository
        
        # Enhanced git log format with proper escaping
        $gitLogFormat = "%H|%h|%an|%ae|%ad|%s"
        $gitCommand = "git log --since=`"$Since`" --pretty=format:`"$gitLogFormat`" --date=iso-strict"
        
        Write-Verbose "Executing: $gitCommand"
        
        $gitOutput = Invoke-Expression $gitCommand 2>$null
        
        if ($LASTEXITCODE -ne 0) {
            throw "Git log command failed with exit code $LASTEXITCODE"
        }
        
        if (-not $gitOutput) {
            Write-Warning "No commits found since $Since"
            return @()
        }
        
        $commits = @()
        foreach ($line in $gitOutput) {
            if ([string]::IsNullOrWhiteSpace($line)) { continue }
            
            $parts = $line -split '\|', 6
            if ($parts.Length -eq 6) {
                $commits += [PSCustomObject]@{
                    hash    = $parts[0]
                    short   = $parts[1] 
                    author  = $parts[2]
                    email   = $parts[3]
                    date    = $parts[4]
                    message = $parts[5]
                }
            }
        }
        
        Write-Verbose "Retrieved $($commits.Count) commits"
        return $commits
        
    } finally {
        Set-Location $currentLocation
    }
}

function Update-CommitAttribution {
    <#
    .SYNOPSIS
    Updates git commit attribution with AI collaboration information.
     
    .DESCRIPTION
    Safely updates commit authors to reflect AI assistance while
    preserving original commit history and providing dry-run capability.
     
    .PARAMETER Commits
    Array of commits with AI analysis results
     
    .PARAMETER DryRun
    Preview changes without applying them
     
    .PARAMETER AIThreshold
    Minimum AI score to trigger attribution update (default: 5.0)
    #>

    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [array]$Commits,
        
        [switch]$DryRun,
        
        [double]$AIThreshold = 5.0
    )
    
    $updatedCount = 0
    $aiCommits = $Commits | Where-Object { $_.AIScore -ge $AIThreshold }
    
    if (-not $aiCommits) {
        Write-Host "No commits found above AI threshold ($AIThreshold)" -ForegroundColor Yellow
        return
    }
    
    Write-Host "`nAI Attribution Update Summary:" -ForegroundColor Cyan
    Write-Host "Threshold: $AIThreshold" -ForegroundColor Gray
    Write-Host "Commits to update: $($aiCommits.Count)" -ForegroundColor Gray
    
    foreach ($commit in $aiCommits) {
        $newAuthorName = "$($commit.Author) + $($commit.PossibleLLM)"
        
        if ($DryRun) {
            Write-Host "`n[DRY RUN] Would update commit: $($commit.ShortHash)" -ForegroundColor Yellow
            Write-Host " Current: $($commit.Author)" -ForegroundColor Gray
            Write-Host " New: $newAuthorName" -ForegroundColor Green  
            Write-Host " AI Score: $($commit.AIScore) ($($commit.AILikelihood))" -ForegroundColor Cyan
            Write-Host " Message: $($commit.Message.Substring(0, [Math]::Min(80, $commit.Message.Length)))" -ForegroundColor Gray
        } else {
            try {
                # Use git filter-branch to update author (careful operation)
                $filterCommand = "git filter-branch --env-filter `"
                    if [ `$GIT_COMMIT = '$($commit.Hash)' ]; then
                        export GIT_AUTHOR_NAME='$newAuthorName'
                        export GIT_COMMITTER_NAME='$newAuthorName'
                    fi
                `" --tag-name-filter cat -- --branches --tags"

                
                Write-Host "Updating commit $($commit.ShortHash)..." -ForegroundColor Yellow
                Invoke-Expression $filterCommand
                
                if ($LASTEXITCODE -eq 0) {
                    $updatedCount++
                    Write-Host " ✓ Updated successfully" -ForegroundColor Green
                } else {
                    Write-Host " ✗ Failed to update" -ForegroundColor Red
                }
            } catch {
                Write-Host " ✗ Error: $($_.Exception.Message)" -ForegroundColor Red
            }
        }
    }
    
    if (-not $DryRun -and $updatedCount -gt 0) {
        Write-Host "`nSuccessfully updated $updatedCount commits" -ForegroundColor Green
        Write-Host "IMPORTANT: Repository history has been rewritten!" -ForegroundColor Red
        Write-Host "Use 'git push --force-with-lease' to update remote repository" -ForegroundColor Yellow
    }
    
    return $updatedCount
}

function Export-AnalysisReport {
    <#
    .SYNOPSIS
    Generates comprehensive AI attribution analysis report.
     
    .DESCRIPTION
    Creates detailed reports in multiple formats (console, JSON, HTML)
    with statistics, visualizations, and actionable insights.
     
    .PARAMETER AnalysisResults
    Array of commit analysis results
     
    .PARAMETER OutputPath
    Directory for output files (default: current directory)
     
    .PARAMETER Format
    Report formats: Console, JSON, HTML, All (default: Console)
    #>

    
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [array]$AnalysisResults,
        
        [string]$OutputPath = (Get-Location),
        
        [ValidateSet("Console", "JSON", "HTML", "All")]
        [string]$Format = "Console"
    )
    
    if (-not $AnalysisResults -or $AnalysisResults.Count -eq 0) {
        Write-Warning "No analysis results to export"
        return
    }
    
    # Calculate comprehensive statistics
    $stats = @{
        TotalCommits = $AnalysisResults.Count
        AIAssistedCommits = ($AnalysisResults | Where-Object { $_.AIScore -ge 3 }).Count
        AverageAIScore = ($AnalysisResults | Measure-Object -Property AIScore -Average).Average
        MaxAIScore = ($AnalysisResults | Measure-Object -Property AIScore -Maximum).Maximum
        LikelihoodDistribution = ($AnalysisResults | Group-Object -Property AILikelihood | 
            ForEach-Object { @{$_.Name = $_.Count} })
        TopLLMs = ($AnalysisResults | Where-Object { $_.PossibleLLM -ne "Human" } | 
            Group-Object -Property PossibleLLM | Sort-Object Count -Descending | 
            Select-Object -First 3 | ForEach-Object { @{$_.Name = $_.Count} })
        MostActiveAuthors = ($AnalysisResults | Group-Object -Property Author | 
            Sort-Object Count -Descending | Select-Object -First 5)
    }
    
    $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
    
    # Console Report
    if ($Format -in @("Console", "All")) {
        Write-Host "`n" + "="*80 -ForegroundColor Cyan
        Write-Host "AI ATTRIBUTION ANALYSIS REPORT" -ForegroundColor Cyan
        Write-Host "="*80 -ForegroundColor Cyan
        Write-Host "Generated: $(Get-Date)" -ForegroundColor Gray
        Write-Host "Repository: $(Split-Path -Leaf (Get-Location))" -ForegroundColor Gray
        
        Write-Host "`nOVERALL STATISTICS:" -ForegroundColor Yellow
        Write-Host " Total Commits Analyzed: $($stats.TotalCommits)" -ForegroundColor White
        Write-Host " AI-Assisted Commits: $($stats.AIAssistedCommits)" -ForegroundColor White
        Write-Host " AI Assistance Rate: $([Math]::Round(($stats.AIAssistedCommits / $stats.TotalCommits) * 100, 1))%" -ForegroundColor Green
        Write-Host " Average AI Score: $([Math]::Round($stats.AverageAIScore, 2))" -ForegroundColor White
        Write-Host " Highest AI Score: $([Math]::Round($stats.MaxAIScore, 2))" -ForegroundColor White
        
        Write-Host "`nAI LIKELIHOOD DISTRIBUTION:" -ForegroundColor Yellow
        foreach ($item in $stats.LikelihoodDistribution) {
            foreach ($key in $item.Keys) {
                $percentage = [Math]::Round(($item[$key] / $stats.TotalCommits) * 100, 1)
                Write-Host " $key`: $($item[$key]) commits ($percentage%)" -ForegroundColor White
            }
        }
        
        if ($stats.TopLLMs) {
            Write-Host "`nTOP AI MODELS DETECTED:" -ForegroundColor Yellow
            foreach ($item in $stats.TopLLMs) {
                foreach ($key in $item.Keys) {
                    Write-Host " $key`: $($item[$key]) commits" -ForegroundColor White
                }
            }
        }
        
        Write-Host "`nHIGH-CONFIDENCE AI COMMITS:" -ForegroundColor Yellow
        $highConfidenceCommits = $AnalysisResults | Where-Object { $_.AIScore -ge 7 } | Sort-Object AIScore -Descending | Select-Object -First 10
        
        foreach ($commit in $highConfidenceCommits) {
            Write-Host " Score: $($commit.AIScore) | $($commit.ShortHash) | $($commit.PossibleLLM)" -ForegroundColor Cyan
            Write-Host " $($commit.Message.Substring(0, [Math]::Min(100, $commit.Message.Length)))" -ForegroundColor Gray
        }
    }
    
    # JSON Report
    if ($Format -in @("JSON", "All")) {
        $jsonReport = @{
            metadata = @{
                generatedAt = Get-Date -Format "o"
                repository = Split-Path -Leaf (Get-Location)
                analysisVersion = "1.0.0"
            }
            statistics = $stats
            commits = $AnalysisResults
        }
        
        $jsonPath = Join-Path $OutputPath "ai-attribution-analysis_$timestamp.json"
        $jsonReport | ConvertTo-Json -Depth 10 | Out-File -FilePath $jsonPath -Encoding utf8
        Write-Host "JSON report saved: $jsonPath" -ForegroundColor Green
    }
    
    # HTML Report (if requested)
    if ($Format -in @("HTML", "All")) {
        $htmlReport = @"
<!DOCTYPE html>
<html>
<head>
    <title>AI Attribution Analysis Report</title>
    <style>
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 40px; }
        .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 10px; }
        .stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 20px 0; }
        .stat-card { background: #f8f9fa; padding: 15px; border-radius: 8px; border-left: 4px solid #007bff; }
        .commits-table { width: 100%; border-collapse: collapse; margin: 20px 0; }
        .commits-table th, .commits-table td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }
        .commits-table th { background-color: #007bff; color: white; }
        .ai-score { font-weight: bold; }
        .high { color: #dc3545; } .medium { color: #fd7e14; } .low { color: #28a745; }
    </style>
</head>
<body>
    <div class="header">
        <h1>AI Attribution Analysis Report</h1>
        <p>Generated: $(Get-Date) | Repository: $(Split-Path -Leaf (Get-Location))</p>
    </div>
     
    <div class="stats">
        <div class="stat-card">
            <h3>Total Commits</h3>
            <p style="font-size: 2em; margin: 0;">$($stats.TotalCommits)</p>
        </div>
        <div class="stat-card">
            <h3>AI-Assisted</h3>
            <p style="font-size: 2em; margin: 0;">$($stats.AIAssistedCommits)</p>
        </div>
        <div class="stat-card">
            <h3>AI Rate</h3>
            <p style="font-size: 2em; margin: 0;">$([Math]::Round(($stats.AIAssistedCommits / $stats.TotalCommits) * 100, 1))%</p>
        </div>
        <div class="stat-card">
            <h3>Avg Score</h3>
            <p style="font-size: 2em; margin: 0;">$([Math]::Round($stats.AverageAIScore, 2))</p>
        </div>
    </div>
     
    <h2>Top AI-Assisted Commits</h2>
    <table class="commits-table">
        <thead>
            <tr><th>Score</th><th>Hash</th><th>Author</th><th>Likely AI</th><th>Message</th></tr>
        </thead>
        <tbody>
"@

        
        $topCommits = $AnalysisResults | Sort-Object AIScore -Descending | Select-Object -First 20
        foreach ($commit in $topCommits) {
            $scoreClass = if ($commit.AIScore -ge 7) { "high" } elseif ($commit.AIScore -ge 3) { "medium" } else { "low" }
            $htmlReport += "<tr><td class='ai-score $scoreClass'>$($commit.AIScore)</td><td>$($commit.ShortHash)</td><td>$($commit.Author)</td><td>$($commit.PossibleLLM)</td><td>$($commit.Message)</td></tr>"
        }
        
        $htmlReport += @"
        </tbody>
    </table>
</body>
</html>
"@

        
        $htmlPath = Join-Path $OutputPath "ai-attribution-report_$timestamp.html"
        $htmlReport | Out-File -FilePath $htmlPath -Encoding utf8
        Write-Host "HTML report saved: $htmlPath" -ForegroundColor Green
    }
}