#Requires -Version 5.1
<#
.SYNOPSIS
    Installs the Blue compiler to %LOCALAPPDATA%\Blue and adds it to the user PATH.

.DESCRIPTION
    Copies blue_bin.exe (as blue.exe), the src/ runtime headers, vendor/ QuickJS
    objects, and supporting JS files to the install directory, then adds that directory
    to the current user's PATH environment variable.

.PARAMETER InstallDir
    Override the default install directory (%LOCALAPPDATA%\Blue).

.PARAMETER Uninstall
    Remove the installed files and remove the install directory from PATH.

.EXAMPLE
    .\install.ps1
    .\install.ps1 -InstallDir C:\Tools\Blue
    .\install.ps1 -Uninstall
#>

param(
    [string]$InstallDir = (Join-Path $env:LOCALAPPDATA 'Blue'),
    [switch]$Uninstall
)

$ErrorActionPreference = 'Stop'
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition

# ── Uninstall ────────────────────────────────────────────────────────────────
if ($Uninstall) {
    if (Test-Path $InstallDir) {
        Remove-Item $InstallDir -Recurse -Force
        Write-Host "Removed $InstallDir"
    } else {
        Write-Host "$InstallDir does not exist — nothing to remove."
    }

    $userPath = [Environment]::GetEnvironmentVariable('PATH', 'User')
    $parts = $userPath -split ';' | Where-Object { $_ -ne '' -and ($_.TrimEnd('\') -ne $InstallDir.TrimEnd('\')) }
    if ($parts.Count -gt 0) {
        [Environment]::SetEnvironmentVariable('PATH', ($parts -join ';'), 'User')
    }
    Write-Host "Removed $InstallDir from user PATH."
    exit 0
}

# ── Locate blue_bin.exe ─────────────────────────────────────────────────────
$srcBin = Join-Path $ScriptDir 'blue_bin.exe'
if (-not (Test-Path $srcBin)) {
    Write-Error @"
blue_bin.exe not found in $ScriptDir.

Build Blue first:
  On Windows with MinGW/MSYS2:  make
  On Windows with MSVC:         nmake   (or use the provided VS solution)

Then re-run this script.
"@
    exit 1
}

# ── C++ compiler check ───────────────────────────────────────────────────────
$cxxFound = $false
foreach ($cxx in @('cl.exe', 'g++.exe', 'clang++.exe', 'c++.exe')) {
    if (Get-Command $cxx -ErrorAction SilentlyContinue) {
        $cxxFound = $true
        Write-Host "Found C++ compiler: $cxx"
        break
    }
}
if (-not $cxxFound) {
    Write-Warning @"
No C++ compiler found (cl.exe, g++.exe, or clang++.exe).
Blue compiles JavaScript to C++ and links it on your machine.

Options:
  - MSVC:   Install Visual Studio with 'Desktop development with C++'
  - MinGW:  MSYS2: pacman -S mingw-w64-ucrt-x86_64-gcc
  - Clang:  winget install LLVM.LLVM

"@
    $continue = Read-Host "Continue installation without a C++ compiler? [y/N]"
    if ($continue -notmatch '^[Yy]') { exit 1 }
}

# ── Create install directory ─────────────────────────────────────────────────
if (-not (Test-Path $InstallDir)) {
    New-Item -ItemType Directory -Path $InstallDir | Out-Null
    Write-Host "Created $InstallDir"
}

# ── Copy binary ──────────────────────────────────────────────────────────────
$destBin = Join-Path $InstallDir 'blue.exe'
Copy-Item -Path $srcBin -Destination $destBin -Force
Write-Host "Installed: blue.exe -> $destBin"

# ── Copy runtime src/ (headers needed when blue compiles user apps) ─────────
$srcSrc = Join-Path $ScriptDir 'src'
if (Test-Path $srcSrc) {
    $destSrc = Join-Path $InstallDir 'src'
    if (Test-Path $destSrc) { Remove-Item $destSrc -Recurse -Force }
    Copy-Item -Path $srcSrc -Destination $destSrc -Recurse
    Write-Host "Copied: src/ -> $destSrc"
} else {
    Write-Warning "src/ not found — blue.exe will not be able to compile apps."
}

# ── Copy vendor/ (prebuilt QuickJS object files) ────────────────────────────
$srcVendor = Join-Path $ScriptDir 'vendor'
if (Test-Path $srcVendor) {
    $destVendor = Join-Path $InstallDir 'vendor'
    if (Test-Path $destVendor) { Remove-Item $destVendor -Recurse -Force }
    Copy-Item -Path $srcVendor -Destination $destVendor -Recurse
    Write-Host "Copied: vendor/ -> $destVendor"
} else {
    Write-Warning "vendor/ not found — hybrid/QuickJS mode will not be available."
}

# ── Copy JS support files ────────────────────────────────────────────────────
foreach ($f in @('esprima.js', 'babel.min.js')) {
    $s = Join-Path $ScriptDir $f
    if (Test-Path $s) {
        Copy-Item -Path $s -Destination (Join-Path $InstallDir $f) -Force
        Write-Host "Copied: $f"
    }
}

# ── Add to user PATH ─────────────────────────────────────────────────────────
$userPath  = [Environment]::GetEnvironmentVariable('PATH', 'User')
$pathParts = $userPath -split ';' | Where-Object { $_ -ne '' }

# Case-insensitive comparison — Windows paths are case-insensitive
$alreadyInPath = $pathParts | Where-Object { $_.TrimEnd('\') -ieq $InstallDir.TrimEnd('\') }

if (-not $alreadyInPath) {
    $newPath = ($pathParts + $InstallDir) -join ';'
    [Environment]::SetEnvironmentVariable('PATH', $newPath, 'User')
    Write-Host ""
    Write-Host "Added to user PATH: $InstallDir"
    Write-Host "Restart your terminal (or run: `$env:PATH += ';$InstallDir') for the change to take effect."
} else {
    Write-Host ""
    Write-Host "$InstallDir is already in PATH."
}

Write-Host ""
Write-Host "Blue installed successfully!"
Write-Host ""
Write-Host "  Quick start:"
Write-Host "    blue --version"
Write-Host "    blue -compile hello.js -o hello.exe"
Write-Host ""
Write-Host "  For WebView2 window support, set WEBVIEW2_SDK_PATH:"
Write-Host "    `$env:WEBVIEW2_SDK_PATH = 'C:\path\to\Microsoft.Web.WebView2'"
Write-Host "  Download from: https://www.nuget.org/packages/Microsoft.Web.WebView2"
