# CheckLocalGitStatus
# 
# Verifica di un set di repo GIT locali rispetto al server origin remoto
# per stabilire quali necessitino di aggiornamento
#
# esempio chiamata: 

# parametri in ingresso
param (
    [string]$RootPath = "C:\Users\samuele.steamw\source",  # Default alla cartella dei sorgenti, da passare invocando il comando
    [switch]$SwitchToMain,
    [string]$OutputFile = "$PSScriptRoot\outdated_repos.txt",
    [switch]$Help
)

$branchesToCheck = @("main", "master")
$outdatedRepos = @()

# Mostra help message se --help or -h passato come argomento
if ($Help -or $args -contains "--help" -or $args -contains "-h") {
    Write-Host @"
Usage: .\Check-GitRepos.ps1 [-RootPath <path>] [-SwitchToMain] [-OutputFile <file>] [--help]

Checks all Git repositories under the specified folder and compares their main/master branch
with the remote origin. Optionally switches to main/master to perform the check.

Parameters:
  -RootPath       Path to the root folder containing Git repositories (default: current script path)
  -SwitchToMain   Temporarily switch to main/master branch to perform the check
  -OutputFile     Path to the output file listing outdated repositories
  --help, -h      Show this help message

Examples:
  .\Check-GitRepos.ps1 -RootPath "D:\Dev\Projects"
  .\Check-GitRepos.ps1 -SwitchToMain
  .\Check-GitRepos.ps1 -RootPath "C:\Code" -SwitchToMain -OutputFile "C:\outdated.txt"
"@ -ForegroundColor Cyan
    exit
}


# Function to check Git status
function Check-GitStatus {
    param (
        [string]$repoPath,
        [string]$OutputFile
    )

    Write-Host "`nChecking repository at: $repoPath" -ForegroundColor Cyan
    Push-Location $repoPath

    if (-not (Test-Path ".git")) {
        Write-Host "Not a Git repository." -ForegroundColor Yellow
        "$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) - Not a Git repository." | Out-File -FilePath $OutputFile -Append -Encoding UTF8
        Pop-Location
        return
    }

    git fetch origin *> $null 2>&1

    $originalBranch = git rev-parse --abbrev-ref HEAD 2>$null

    $remoteBranches = git ls-remote --heads origin | ForEach-Object {
        ($_ -split "\s+")[1] -replace "refs/heads/", ""
    }

    $targetBranch = $branchesToCheck | Where-Object { $remoteBranches -contains $_ } | Select-Object -First 1

    if (-not $targetBranch) {
        $message = "$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) - MISSING | $repoPath No 'main' or 'master' branch found on remote."
        Write-Host $message -ForegroundColor Red
        $message | Out-File -FilePath $OutputFile -Append -Encoding UTF8
        Pop-Location
        return
    }

    if ($SwitchToMain -and $originalBranch -ne $targetBranch) {
        git stash push -u -m "Temp stash before switching branches" *> $null 2>&1
        git checkout $targetBranch *> $null 2>&1
    }

    $status = git status -sb 2>$null
    $aheadBehind = git rev-list --left-right --count origin/$targetBranch...HEAD 2>$null

    if ($aheadBehind) {
        $parts = $aheadBehind -split "`t"
        $behind = [int]$parts[0]
        $ahead = [int]$parts[1]

        if ($ahead -gt 0 -or $behind -gt 0) {
            $message = "$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) - UPDATE | $repoPath is not up to date with origin/$targetBranch (ahead: $ahead, behind: $behind)"
            Write-Host $message -ForegroundColor Yellow
            $message | Out-File -FilePath $OutputFile -Append -Encoding UTF8
            $script:hasOutdated = $true
        } else {
            Write-Host "✅ Repo is up to date with origin/$targetBranch" -ForegroundColor Green
        }
    }

    if ($SwitchToMain -and $originalBranch -ne $targetBranch) {
        git checkout $originalBranch *> $null 2>&1
        git stash pop *> $null 2>&1
    }

    Pop-Location
}

# Get all subdirectories containing .git folders
$repos = Get-ChildItem -Path $RootPath -Recurse -Directory | Where-Object {
    Test-Path "$($_.FullName)\.git"
}

# Clear or create output file
"" | Out-File -FilePath $OutputFile -Encoding UTF8
$script:hasOutdated = $false

# Check each repository
foreach ($repo in $repos) {
    Check-GitStatus -repoPath $repo.FullName -OutputFile $OutputFile
}

# Final summary
if ($script:hasOutdated) {
    Write-Host "`n📄 Outdated repositories saved to: $OutputFile" -ForegroundColor Cyan
} else {
    $msg = "🎉 All repositories are up to date!"
    Write-Host "`n$msg" -ForegroundColor Green
    $msg = "$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss')) - 🎉 All repositories are up to date!"
    $msg | Out-File -FilePath $OutputFile -Append -Encoding UTF8
}
