<#
.SYNOPSIS
Bootstrap a Python virtualenv and install the project on Windows (PowerShell).

.DESCRIPTION
Creates a Python virtual environment (default: .venv), upgrades pip, installs the project
(either editable or normal), and optionally creates Desktop and Start Menu shortcuts.

.EXAMPLE
# Create .venv and install in editable mode, create Desktop shortcut
.\scripts\bootstrap.ps1 -Editable -CreateDesktopShortcut

.EXAMPLE
# Use a specific python executable and force overwrite existing venv
.\scripts\bootstrap.ps1 -Python "C:\\Python39\\python.exe" -Force
# Note: you may need to run PowerShell with ExecutionPolicy Bypass:
# powershell -ExecutionPolicy Bypass -File .\scripts\bootstrap.ps1 -Editable
#>

param(
    [switch]$Editable,
    [switch]$CreateDesktopShortcut,
    [switch]$CreateStartMenuShortcut,
    [string]$VenvPath = ".venv",
    [string]$Python = "",
    [switch]$Force,
    [switch]$NoInstall,
    [switch]$NoPlaywright,
    [string]$PlaywrightBrowsers = "chromium",
    [switch]$FixUrllib3,
    [switch]$RemovePth,
    [switch]$Quiet
)

# Resolve OS detection in a broad-compatible way
try { $IsWindowsPlatform = [System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Windows) } catch { $IsWindowsPlatform = $env:OS -match 'Windows' }

function Write-Log {
    param([string]$msg,[string]$lvl="INFO")
    if (-not $Quiet) {
        if ($lvl -eq "ERROR") { Write-Host "[$lvl] $msg" -ForegroundColor Red } else { Write-Host "[$lvl] $msg" }
    }
}

function Ensure-Mpv {
    # mpv is used by some pipelines; try to ensure it's available on PATH.
    try {
        $mpvCmd = Get-Command mpv -ErrorAction SilentlyContinue
        if ($mpvCmd) {
            try {
                $v = & mpv --version 2>$null | Select-Object -First 1
                if ($v) { Write-Log "mpv found: $v" "INFO" } else { Write-Log "mpv found: $($mpvCmd.Path)" "INFO" }
            } catch {
                Write-Log "mpv found: $($mpvCmd.Path)" "INFO"
            }
            return
        }
    } catch {}

    Write-Log "mpv not found on PATH; attempting to install..." "INFO"

    try {
        if (Get-Command choco -ErrorAction SilentlyContinue) {
            & choco install mpv -y --no-progress | Out-Null
        } elseif (Get-Command scoop -ErrorAction SilentlyContinue) {
            & scoop install mpv | Out-Null
        } elseif (Get-Command winget -ErrorAction SilentlyContinue) {
            # Best-effort: winget may require a specific id depending on environment.
            & winget install --silent --accept-package-agreements --accept-source-agreements mpv | Out-Null
        } else {
            Write-Log "mpv not found and no supported package manager found (choco/scoop/winget). Install mpv and ensure it's on PATH." "ERROR"
            return
        }
    } catch {
        Write-Log "mpv install attempt failed: $_" "ERROR"
        return
    }

    try {
        $mpvCmd2 = Get-Command mpv -ErrorAction SilentlyContinue
        if ($mpvCmd2) {
            try {
                $v2 = & mpv --version 2> $null | Select-Object -First 1
                if ($v2) { Write-Log "mpv installed: $v2" "INFO" } else { Write-Log "mpv installed: $($mpvCmd2.Path)" "INFO" }
            } catch {
                Write-Log "mpv installed: $($mpvCmd2.Path)" "INFO"
            }
        } else {
            Write-Log "mpv install attempted but mpv is still not on PATH. Install mpv manually." "ERROR"
        }
    } catch {}
}

if ($IsWindowsPlatform) {
    Ensure-Mpv
}

# Track whether the user chose an interactive auto-fix (so we can auto-remove .pth files)
$AutoFixInteractive = $false

function Find-Python {
    param([string]$preferred)
    $candidates = @()
    if ($preferred -and $preferred.Trim()) { $candidates += $preferred }
    $candidates += @("python","python3","py")
    foreach ($c in $candidates) {
        try {
            if ($c -eq "py") {
                $out = & py -3 -c "import sys, json; print(sys.executable)" 2>$null
                if ($out) { return $out.Trim() }
            } else {
                $out = & $c -c "import sys, json; print(sys.executable)" 2>$null
                if ($out) { return $out.Trim() }
            }
        } catch {}
    }
    return $null
}

# operate from repo root (parent of scripts dir)
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$repoRoot = (Resolve-Path (Join-Path $scriptDir "..")).Path
Set-Location $repoRoot
$scriptsDir = Join-Path $repoRoot 'scripts'

$pythonExe = Find-Python -preferred $Python
if (-not $pythonExe) { Write-Log "No Python interpreter found. Specify -Python <path> or install Python." "ERROR"; exit 2 }
Write-Log "Using Python: $pythonExe"

# Full venv path
try { $venvFull = (Resolve-Path -LiteralPath $VenvPath -ErrorAction SilentlyContinue).Path } catch { $venvFull = $null }
if (-not $venvFull) { $venvFull = (Join-Path $repoRoot $VenvPath) }

# Handle existing venv
$venvExists = Test-Path $venvFull
if ($venvExists) {
    if ($Force) {
        Write-Log "Removing existing venv at $venvFull"
        Remove-Item -Recurse -Force $venvFull
        $venvExists = $false
    } else {
        # Quick health check: does the existing venv have a python executable?
        $venvPy1 = Join-Path $venvFull "Scripts\python.exe"
        $venvPy2 = Join-Path $venvFull "bin/python"
        $venvHasPython = $false
        try {
            if (Test-Path $venvPy1 -PathType Leaf -ErrorAction SilentlyContinue) { $venvHasPython = $true }
            elseif (Test-Path $venvPy2 -PathType Leaf -ErrorAction SilentlyContinue) { $venvHasPython = $true }
        } catch {}

        if (-not $venvHasPython) {
            if ($Quiet) {
                Write-Log "Existing venv appears incomplete or broken and quiet mode prevents prompting. Use -Force to recreate." "ERROR"
                exit 4
            }
            $ans = Read-Host "$venvFull exists but appears invalid (no python executable). Overwrite to recreate? (y/N)"
            if ($ans -eq 'y' -or $ans -eq 'Y') {
                Write-Log "Removing broken venv at $venvFull"
                Remove-Item -Recurse -Force $venvFull
                $venvExists = $false
            } else {
                Write-Log "Aborted due to broken venv." "ERROR"; exit 4
            }
        } else {
            if ($Quiet) {
                Write-Log "Using existing venv at $venvFull (quiet mode)" "INFO"
            } else {
                $ans = Read-Host "$venvFull already exists. Overwrite? (y/N) (default: use existing venv)"
                if ($ans -eq 'y' -or $ans -eq 'Y') {
                    Write-Log "Removing existing venv at $venvFull"
                    Remove-Item -Recurse -Force $venvFull
                    $venvExists = $false
                } else {
                    Write-Log "Continuing using existing venv at $venvFull" "INFO"
                }
            }
        }
    }
}

if (-not (Test-Path $venvFull)) {
    Write-Log "Creating venv at $venvFull"
    try {
        & $pythonExe -m venv $venvFull
    } catch {
        Write-Log "Failed to create venv: $_" "ERROR"; exit 3
    }
} else {
    Write-Log "Using existing venv at $venvFull" "INFO"
}

# Determine venv python executable
$venvPython = Join-Path $venvFull "Scripts\python.exe"
if (-not (Test-Path $venvPython)) { $venvPython = Join-Path $venvFull "bin/python" }
if (-not (Test-Path $venvPython)) { Write-Log "Created venv but could not find python inside it." "ERROR"; exit 4 }

Write-Log "Using venv python: $venvPython"

if (-not $NoInstall) {
    # Suggest editable install for development checkouts (interactive git clones)
    if (-not $Editable) {
        $isGit = $false
        try {
            if (Test-Path (Join-Path $repoRoot '.git')) { $isGit = $true }
            elseif ((Get-Command git -ErrorAction SilentlyContinue) -ne $null) {
                try { $gitOut = & git -C $repoRoot rev-parse --is-inside-work-tree 2>$null; if ($gitOut -eq 'true') { $isGit = $true } } catch {}
            }
        } catch {}
        if ($isGit) {
            $Editable = $true
            Write-Log "Detected development checkout; installing in editable mode for development." "INFO"
        }
    }

    Write-Log "Upgrading pip, setuptools, wheel"
    try { & $venvPython -m pip install -U pip setuptools wheel } catch { Write-Log "pip upgrade failed: $_" "ERROR"; exit 5 }

    if ($Editable) { $editable_label = "(editable)" } else { $editable_label = "" }
    Write-Log ("Installing project {0}" -f $editable_label)
    try {
        if ($Editable) { & $venvPython -m pip install -e $scriptsDir } else { & $venvPython -m pip install $scriptsDir }
    } catch {
        Write-Log "pip install failed: $_" "ERROR"; exit 6
    }

    # Verify top-level 'CLI' import and (if missing) attempt to make it available
    Write-Log "Verifying installed CLI import..."
    try {
        & $venvPython -c "import importlib; importlib.import_module('scripts.cli_entry')" 2>$null
        if ($LASTEXITCODE -eq 0) { Write-Log "OK: 'scripts.cli_entry' is importable in the venv." }
    } catch {}

    try {
        & $venvPython -c "import importlib; importlib.import_module('CLI')" 2>$null
        if ($LASTEXITCODE -eq 0) { Write-Log "Top-level 'CLI' is importable in the venv." }
        else {
            Write-Log "Top-level 'CLI' not importable; writing venv site-packages .pth pointing at repo root..." "INFO"

            $siteDir = (& $venvPython -c "import sysconfig; print(sysconfig.get_paths().get('purelib',''))" 2>$null).Trim()
            if (-not $siteDir -or -not (Test-Path $siteDir)) {
                Write-Log "ERROR: unable to determine venv site-packages directory (purelib='$siteDir'); aborting." "ERROR"
                exit 6
            }

            $pth = Join-Path $siteDir 'medeia_repo.pth'
            Set-Content -LiteralPath $pth -Value $repoRoot -Encoding UTF8
            Write-Log "Wrote .pth adding repo root to venv site-packages: $pth" "INFO"

            & $venvPython -c "import importlib; importlib.import_module('CLI')" 2>$null
            if ($LASTEXITCODE -eq 0) {
                Write-Log "OK: top-level 'CLI' is now importable (after .pth)." "INFO"
            } else {
                Write-Log "ERROR: top-level 'CLI' still not importable after writing .pth ($pth); aborting." "ERROR"
                exit 6
            }
        }
    } catch {
        Write-Log "Failed to verify top-level 'CLI': $_" "ERROR"
        exit 6
    }

    # Install Playwright browsers (default: chromium) unless explicitly disabled
    if (-not $NoPlaywright) {
        Write-Log "Ensuring Playwright browsers are installed (browsers=$PlaywrightBrowsers)..."
        try {
            & $venvPython -c "import importlib; importlib.import_module('playwright')" 2>$null
            if ($LASTEXITCODE -ne 0) {
                Write-Log "'playwright' package not found in venv; installing via pip..."
                & $venvPython -m pip install playwright
            }
        } catch {
            Write-Log "Failed to check/install 'playwright' package: $_" "ERROR"
        }

        try {
            if ($PlaywrightBrowsers -eq 'all') {
                Write-Log "Installing all Playwright browsers..."
                & $venvPython -m playwright install
            } else {
                $list = $PlaywrightBrowsers -split ','
                foreach ($b in $list) {
                    $btrim = $b.Trim()
                    if ($btrim) {
                        Write-Log "Installing Playwright browser: $btrim"
                        & $venvPython -m playwright install $btrim
                    }
                }
            }
        } catch {
            Write-Log "Playwright browser install failed: $_" "ERROR"
        }
    }

    # Verify environment for known package conflicts (urllib3 compatibility)
    Write-Log "Verifying environment for known package conflicts (urllib3 compatibility)..."
    try {
        & $venvPython -c "import sys; from SYS.env_check import check_urllib3_compat; ok, msg = check_urllib3_compat(); print(msg); sys.exit(0 if ok else 2)"
        if ($LASTEXITCODE -ne 0) {
            Write-Log "Bootstrap detected a potentially broken 'urllib3' installation. See message above." "ERROR"
            Write-Log "Suggested fixes (activate the venv first):" "INFO"
            Write-Log "  $ $venvPython -m pip uninstall urllib3-future -y" "INFO"
            Write-Log "  $ $venvPython -m pip install --upgrade --force-reinstall urllib3" "INFO"
            Write-Log "  $ $venvPython -m pip install niquests -U" "INFO"

            function Get-SitePackages {
                param($python)
                try {
                    $json = & $python -c "import site, sysconfig, json; p=[]; 
try:
    p.extend(site.getsitepackages())
except Exception:
    pass
try:
    pp = sysconfig.get_paths().get('purelib')
    if pp:
        p.append(pp)
except Exception:
    pass
seen = []
out = []
for s in p:
    if s and s not in seen:
        seen.append(s)
        out.append(s)
print(json.dumps(out))"
                    return $json | ConvertFrom-Json
                } catch {
                    return @()
                }
            }

            function Find-InterferingPth {
                param($python)
                $pths = @()
                $sps = Get-SitePackages -python $python
                foreach ($sp in $sps) {
                    if (Test-Path $sp) {
                        Get-ChildItem -Path $sp -Filter *.pth -File -ErrorAction SilentlyContinue | ForEach-Object {
                            $c = Get-Content -Path $_.FullName -ErrorAction SilentlyContinue | Out-String
                            if ($c -match 'urllib3_future' -or $c -match 'urllib3-future') {
                                $pths += $_.FullName
                            }
                        }
                    }
                }
                return $pths
            }

            # Helper to try removal and re-verify
            function RemovePthAndVerify {
                param($python, $paths)
                foreach ($p in $paths) { Remove-Item -Force $p -ErrorAction SilentlyContinue }
                try { & $python -m pip install --upgrade --force-reinstall urllib3 } catch { Write-Log "pip install failed: $_" "ERROR"; return $false }
                & $python -c "import sys; from SYS.env_check import check_urllib3_compat; ok, msg = check_urllib3_compat(); print(msg); sys.exit(0 if ok else 2)"
                return ($LASTEXITCODE -eq 0)
            }

            if ($FixUrllib3) {
                Write-Log "Attempting automatic fix (--FixUrllib3)..." "INFO"
                try { & $venvPython -m pip uninstall urllib3-future -y } catch {}
                try { & $venvPython -m pip install --upgrade --force-reinstall urllib3 } catch { Write-Log "pip install failed: $_" "ERROR"; exit 7 }
                try { & $venvPython -m pip install niquests -U } catch { Write-Log "pip install niquests failed: $_" "ERROR" }
                & $venvPython -c "import sys; from SYS.env_check import check_urllib3_compat; ok, msg = check_urllib3_compat(); print(msg); sys.exit(0 if ok else 2)"
                if ($LASTEXITCODE -eq 0) {
                    Write-Log "Success: urllib3 problems appear resolved; continuing." "INFO"
                } else {
                    Write-Log "Initial automatic fix did not resolve the issue; searching for interfering .pth files..." "INFO"
                    $pths = Find-InterferingPth -python $venvPython
                    if ($pths.Count -eq 0) {
                        Write-Log "No interfering .pth files found; aborting." "ERROR"
                        exit 7
                    }
                    Write-Log ("Found interfering .pth files:`n" + ($pths -join "`n")) "ERROR"
                    if ($RemovePth) {
                        Write-Log "Removing .pth files as requested..." "INFO"
                        if (RemovePthAndVerify -python $venvPython -paths $pths) {
                            Write-Log "Success: urllib3 problems resolved after .pth removal; continuing." "INFO"
                        } else {
                            Write-Log "Automatic fix failed even after .pth removal; aborting." "ERROR"
                            exit 7
                        }
                    } else {
                        if ($Quiet) { Write-Log "Detected interfering .pth files but cannot prompt in quiet mode. Use -RemovePth to remove them automatically." "ERROR"; exit 7 }
                        $ans = Read-Host "Remove these files now? (y/N)"
                        if ($ans -eq 'y' -or $ans -eq 'Y') {
                            if (RemovePthAndVerify -python $venvPython -paths $pths) {
                                Write-Log "Success: urllib3 problems resolved after .pth removal; continuing." "INFO"
                            } else {
                                Write-Log "Automatic fix failed even after .pth removal; aborting." "ERROR"
                                exit 7
                            }
                        } else {
                            Write-Log "User declined to remove .pth files. Aborting." "ERROR"
                            exit 7
                        }
                    }
                }
            } else {
                if ($Quiet) {
                    Write-Log "Bootstrap detected a potentially broken 'urllib3' installation. Use -FixUrllib3 to attempt an automatic fix." "ERROR"
                    exit 7
                }
                $ans = Read-Host "Attempt automatic fix now? (y/N)"
                if ($ans -eq 'y' -or $ans -eq 'Y') {
                    $AutoFixInteractive = $true
                    try { & $venvPython -m pip uninstall urllib3-future -y } catch {}
                    try { & $venvPython -m pip install --upgrade --force-reinstall urllib3 } catch { Write-Log "pip install failed: $_" "ERROR"; exit 7 }
                    try { & $venvPython -m pip install niquests -U } catch { Write-Log "pip install niquests failed: $_" "ERROR" }
                    & $venvPython -c "import sys; from SYS.env_check import check_urllib3_compat; ok, msg = check_urllib3_compat(); print(msg); sys.exit(0 if ok else 2)"
                    if ($LASTEXITCODE -eq 0) {
                        Write-Log "Success: urllib3 problems appear resolved; continuing." "INFO"
                    } else {
                        Write-Log "Initial automatic fix did not resolve the issue; searching for interfering .pth files..." "INFO"
                        $pths = Find-InterferingPth -python $venvPython
                        if ($pths.Count -eq 0) {
                            Write-Log "No interfering .pth files found; aborting." "ERROR"
                            exit 7
                        }
                        Write-Log ("Found interfering .pth files:`n" + ($pths -join "`n")) "ERROR"
                        if ($RemovePth -or $AutoFixInteractive -or $FixUrllib3) {
                            Write-Log "Removing .pth files automatically..." "INFO"
                            if (RemovePthAndVerify -python $venvPython -paths $pths) {
                                Write-Log "Success: urllib3 problems resolved after .pth removal; continuing." "INFO"
                            } else {
                                Write-Log "Automatic fix failed even after .pth removal; aborting." "ERROR"
                                exit 7
                            }
                        } else {
                            $ans2 = Read-Host "Remove these files now? (y/N)"
                            if ($ans2 -eq 'y' -or $ans2 -eq 'Y') {
                                if (RemovePthAndVerify -python $venvPython -paths $pths) {
                                    Write-Log "Success: urllib3 problems resolved after .pth removal; continuing." "INFO"
                                } else {
                                    Write-Log "Automatic fix failed even after .pth removal; aborting." "ERROR"
                                    exit 7
                                }
                            } else {
                                Write-Log "User declined to remove .pth files. Aborting." "ERROR"
                                exit 7
                            }
                        }
                    }
                } else {
                    Write-Log "Aborting bootstrap to avoid leaving a broken environment." "ERROR"
                    exit 7
                }
            }
        }
    } catch {
        Write-Log "Failed to run environment verification: $_" "ERROR"
    }

    Write-Log "Deno is already installed: $($denoCmd.Path)"
} else {
    Write-Log "Installing Deno via official installer (https://deno.land)"
    try {
        try {
            irm https://deno.land/install.ps1 | iex
        } catch {
            iwr https://deno.land/install.ps1 -UseBasicParsing | iex
        }
        # Ensure common install locations are on PATH for this session
        $denoCandidatePaths = @(
            Join-Path $env:USERPROFILE ".deno\bin",
            Join-Path $env:LOCALAPPDATA "deno\bin"
        )
        foreach ($p in $denoCandidatePaths) {
            if (Test-Path $p) {
                if ($env:PATH -notmatch [regex]::Escape($p)) {
                    $env:PATH = $env:PATH + ";" + $p
                }
            }
        }
        $v = & deno --version 2>$null
        if ($v) {
            Write-Log "Deno installed: $v"
        } else {
            Write-Log "Deno installer completed but 'deno' not found on PATH; you may need to restart your shell or add the Deno bin folder to PATH." "ERROR"
        }
    } catch {
        Write-Log "Deno install failed: $_" "ERROR"
    }
}

# Shortcuts (Windows only)
if ($IsWindowsPlatform) {
    if ($CreateDesktopShortcut -or $CreateStartMenuShortcut) {
        $wsh = New-Object -ComObject WScript.Shell
        $mmExe = Join-Path $venvFull "Scripts\mm.exe"
        $target = $null
        $args = ""
        if (Test-Path $mmExe) {
            $target = $mmExe
        } else {
            $target = $venvPython
            $args = "-m scripts.cli_entry"
        }
        if ($CreateDesktopShortcut) {
            $desk = [Environment]::GetFolderPath('Desktop')
            $link = Join-Path $desk "Medeia-Macina.lnk"
            Write-Log "Creating Desktop shortcut: $link"
            $sc = $wsh.CreateShortcut($link)
            $sc.TargetPath = $target
            $sc.Arguments = $args
            $sc.WorkingDirectory = $repoRoot
            $sc.IconLocation = "$target,0"
            $sc.Save()
        }
        if ($CreateStartMenuShortcut) {
            $start = Join-Path ([Environment]::GetFolderPath('ApplicationData')) 'Microsoft\Windows\Start Menu\Programs'
            $dir = Join-Path $start "Medeia-Macina"
            New-Item -ItemType Directory -Path $dir -Force | Out-Null
            $link2 = Join-Path $dir "Medeia-Macina.lnk"
            Write-Log "Creating Start Menu shortcut: $link2"
            $sc2 = $wsh.CreateShortcut($link2)
            $sc2.TargetPath = $target
            $sc2.Arguments = $args
            $sc2.WorkingDirectory = $repoRoot
            $sc2.IconLocation = "$target,0"
            $sc2.Save()
        }
    }
}

# Install global 'mm' launcher into the user's bin directory so it can be invoked from any shell.
try {
    $globalBin = Join-Path $env:USERPROFILE 'bin'
    New-Item -ItemType Directory -Path $globalBin -Force | Out-Null

    $mmPs1 = Join-Path $globalBin 'mm.ps1'

    $repo = $repoRoot

    # PowerShell shim: use single-quoted here-string so literal PowerShell variables
    # (like $args) are not expanded by this script when writing the file.
    $ps1Text = @'
Param([Parameter(ValueFromRemainingArguments=$true)] $args)
$repo = "__REPO__"
$venv = Join-Path $repo '.venv'
$exe = Join-Path $venv 'Scripts\mm.exe'
if (Test-Path $exe) { & $exe @args; exit $LASTEXITCODE }
$py = Join-Path $venv 'Scripts\python.exe'
if ($env:MM_DEBUG) {
    Write-Host "MM_DEBUG: diagnostics" -ForegroundColor Yellow
    if (Test-Path $py) { & $py -c "import sys,importlib,importlib.util,traceback; print('sys.executable:', sys.executable); print('sys.path (first 8):', sys.path[:8]);" }
    else { python -c "import sys,importlib,importlib.util,traceback; print('sys.executable:', sys.executable); print('sys.path (first 8):', sys.path[:8]);" }
}
if (Test-Path $py) { & $py -m scripts.cli_entry @args; exit $LASTEXITCODE }
if (Test-Path (Join-Path $repo 'CLI.py')) { & python (Join-Path $repo 'CLI.py') @args; exit $LASTEXITCODE }
# fallback
python -m scripts.cli_entry @args
'@
# Thin wrapper: prefer the canonical Python bootstrap installer
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$repo = (Resolve-Path (Join-Path $scriptDir "..")).Path
$venvPy = Join-Path $repo '.venv\Scripts\python.exe'

# Normalize incoming quiet flag (-Quiet) into -q for the Python script
$forwardArgs = @()
foreach ($a in $args) {
    if ($a -eq '-Quiet') { $forwardArgs += '-q' } else { $forwardArgs += $a }
}

# Debug helper
if ($env:MM_DEBUG) { Write-Host "MM_DEBUG: invoking python installer with args: $forwardArgs" -ForegroundColor Yellow }

if (Test-Path $venvPy) {
    & $venvPy (Join-Path $repo 'scripts\bootstrap.py') --no-delegate @forwardArgs
    exit $LASTEXITCODE
}

# Fall back to any system Python (py -3 -> python3 -> python)
if (Get-Command -Name py -ErrorAction SilentlyContinue) {
    & py -3 (Join-Path $repo 'scripts\bootstrap.py') --no-delegate @forwardArgs
    exit $LASTEXITCODE
}
if (Get-Command -Name python3 -ErrorAction SilentlyContinue) {
    & python3 (Join-Path $repo 'scripts\bootstrap.py') --no-delegate @forwardArgs
    exit $LASTEXITCODE
}
if (Get-Command -Name python -ErrorAction SilentlyContinue) {
    & python (Join-Path $repo 'scripts\bootstrap.py') --no-delegate @forwardArgs
    exit $LASTEXITCODE
}

Write-Host 'Error: no suitable Python 3 interpreter found. Please install Python 3 or use the venv.' -ForegroundColor Red
exit 127
