$ErrorActionPreference = "Stop"

Write-Host "=== Whisper Dictation Builder ===" -ForegroundColor Cyan
Write-Host ""

$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
$RepoRoot = Resolve-Path "$ScriptDir/.."
$DepsDir = "$RepoRoot/deps"
$BuildDir = "$RepoRoot/build"
$SdlVer = "2.28.5"
$SdlDirName = "SDL2-$SdlVer"
$SdlPath = "$DepsDir/$SdlDirName"

# Detect available GPU backends
$UseGPU = $false
$GPUBackend = "none"

Write-Host "[1/6] Detecting GPU capabilities..." -ForegroundColor Yellow

# Check for NVIDIA GPU
try {
    $NvidiaGpu = Get-WmiObject Win32_VideoController | Where-Object { $_.Name -like "*NVIDIA*" }
    if ($NvidiaGpu) {
        Write-Host "  [OK] NVIDIA GPU detected: $($NvidiaGpu.Name)" -ForegroundColor Green
        
        # Check for CUDA
        $CudaPath = $env:CUDA_PATH
        if (!$CudaPath) {
            # Try to find latest CUDA version if CUDA_PATH not set
            $cudaDir = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA"
            if (Test-Path $cudaDir) {
                $versions = Get-ChildItem $cudaDir -Directory | Sort-Object Name -Descending
                if ($versions.Count -gt 0) {
                    $CudaPath = $versions[0].FullName
                    Write-Host "  [INFO] Found CUDA at: $CudaPath" -ForegroundColor Cyan
                }
            }
        }
        
        if ($CudaPath -and (Test-Path "$CudaPath\bin\nvcc.exe")) {
            # Check CUDA version
            $nvccOutput = (& "$CudaPath\bin\nvcc.exe" --version 2>&1) -join "`n"
            if ($nvccOutput -match "release\s+(\d+)\.(\d+)") {
                $cudaMajor = [int]$matches[1]
                $cudaMinor = [int]$matches[2]
                
                if ($cudaMajor -ge 12) {
                    Write-Host "  [OK] CUDA $cudaMajor.$cudaMinor toolkit - EXCELLENT!" -ForegroundColor Green
                    Write-Host "  [OK] Full GPU acceleration enabled" -ForegroundColor Green
                    $UseGPU = $true
                    $GPUBackend = "cuda"
                } elseif ($cudaMajor -eq 11 -and $cudaMinor -ge 7) {
                    Write-Host "  [OK] CUDA $cudaMajor.$cudaMinor toolkit found" -ForegroundColor Yellow
                    Write-Host "  [WARN] CUDA 12.4+ recommended for MSVC 2022, will try anyway" -ForegroundColor Yellow
                    $UseGPU = $true
                    $GPUBackend = "cuda"
                } else {
                    Write-Host "  [WARN] CUDA $cudaMajor.$cudaMinor is too old (need 11.7+)" -ForegroundColor Yellow
                }
            } else {
                Write-Host "  [WARN] Could not parse CUDA version from nvcc" -ForegroundColor Yellow
            }
        } else {
            Write-Host "  [WARN] CUDA toolkit not found or nvcc.exe missing" -ForegroundColor Yellow
            Write-Host "  [INFO] After installing CUDA 13.0, restart your terminal" -ForegroundColor Cyan
        }
    }
} catch {
    Write-Host "  [WARN] GPU detection error: $_" -ForegroundColor Yellow
    Write-Host "  [INFO] Falling back to CPU-only" -ForegroundColor Gray
}

# Check for AMD GPU
try {
    $AmdGpu = Get-WmiObject Win32_VideoController | Where-Object { $_.Name -like "*AMD*" -or $_.Name -like "*Radeon*" }
    if ($AmdGpu -and !$UseGPU) {
        Write-Host "  [OK] AMD GPU detected: $($AmdGpu.Name)" -ForegroundColor Green
        Write-Host "  [INFO] ROCm support available but requires manual setup" -ForegroundColor Cyan
    }
} catch {
    # Ignore
}

# Check for Vulkan
if (!$UseGPU) {
    $VulkanSDK = $env:VULKAN_SDK
    if ($VulkanSDK -and (Test-Path "$VulkanSDK")) {
        $UseGPU = $true
        $GPUBackend = "vulkan"
        Write-Host "  [OK] Vulkan SDK found at: $VulkanSDK" -ForegroundColor Green
    }
}

if (!$UseGPU) {
    Write-Host "  -> Building with optimized multi-core CPU" -ForegroundColor Cyan
    Write-Host "     Using all $env:NUMBER_OF_PROCESSORS CPU threads for maximum performance" -ForegroundColor Gray
    Write-Host "     (To enable GPU: Install CUDA 12.4+ or Vulkan SDK)" -ForegroundColor DarkGray
}

Write-Host ""

# Setup SDL2
Write-Host "[2/6] Setting up SDL2..." -ForegroundColor Yellow
if (-not (Test-Path "$SdlPath/cmake/sdl2-config.cmake")) {
    if (-not (Test-Path $DepsDir)) { New-Item -ItemType Directory -Path $DepsDir | Out-Null }
    $ZipFile = "$DepsDir/SDL2-devel-$SdlVer-VC.zip"
    $Url = "https://github.com/libsdl-org/SDL/releases/download/release-$SdlVer/SDL2-devel-$SdlVer-VC.zip"
    
    Write-Host "  Downloading SDL2..." -NoNewline
    if (-not (Test-Path $ZipFile)) { 
        Invoke-WebRequest -Uri $Url -OutFile $ZipFile 
    }
    Write-Host " Done" -ForegroundColor Green
    
    Write-Host "  Extracting..." -NoNewline
    Expand-Archive -Path $ZipFile -DestinationPath $DepsDir -Force
    Write-Host " Done" -ForegroundColor Green
} else {
    Write-Host "  [OK] SDL2 already configured" -ForegroundColor Green
}

Write-Host ""

# Configure CMake
Write-Host "[3/6] Configuring CMake..." -ForegroundColor Yellow
Set-Location $RepoRoot

$SdlPathResolved = Resolve-Path $SdlPath -ErrorAction SilentlyContinue
if (-not $SdlPathResolved) {
    $SdlPathResolved = $SdlPath
}
# Convert to forward slashes for CMake
$SdlDir = ($SdlPathResolved -replace '\\', '/') + '/cmake'

$CMakeArgs = @(
    "-S", $RepoRoot,
    "-B", "build",
    "-DWHISPER_SDL2=ON",
    "-DSDL2_DIR=$SdlDir"
)

# Add GPU backend flags
if ($UseGPU) {
    if ($GPUBackend -eq "cuda") {
        Write-Host "  Enabling CUDA backend..." -ForegroundColor Cyan
        $CMakeArgs += "-DGGML_CUDA=ON"
        # Explicitly set CUDA_PATH to avoid finding old versions
        if ($CudaPath) {
            $env:CUDA_PATH = $CudaPath
            $env:CUDA_HOME = $CudaPath
            # Force CMake to use this specific toolkit root
            $CMakeArgs += "-DCUDAToolkit_ROOT=$CudaPath"
            Write-Host "  Setting CUDA_PATH to: $CudaPath" -ForegroundColor Cyan
        }
    } elseif ($GPUBackend -eq "vulkan") {
        Write-Host "  Enabling Vulkan backend..." -ForegroundColor Cyan
        $CMakeArgs += "-DGGML_VULKAN=ON"
    }
} else {
    Write-Host "  Building CPU-only with all cores..." -ForegroundColor Cyan
    # Explicitly disable all GPU backends
    $CMakeArgs += "-DGGML_CUDA=OFF"
    $CMakeArgs += "-DGGML_VULKAN=OFF"
    $CMakeArgs += "-DGGML_METAL=OFF"
    $CMakeArgs += "-DGGML_HIPBLAS=OFF"
}

# Run CMake
& cmake @CMakeArgs

if ($LASTEXITCODE -ne 0) {
    Write-Host ""
    Write-Host "[WARN] CMake configuration had warnings, but continuing..." -ForegroundColor Yellow
    if ($UseGPU) {
        Write-Host "  GPU backend may not be available. Will use CPU fallback." -ForegroundColor Yellow
    }
}

Write-Host ""

# Build
Write-Host "[4/6] Building win-dictation..." -ForegroundColor Yellow
cmake --build build --config Release --target win-dictation -j $env:NUMBER_OF_PROCESSORS

if ($LASTEXITCODE -ne 0) {
    Write-Host ""
    Write-Host "[ERROR] Build failed!" -ForegroundColor Red
    exit 1
}

Write-Host "  [OK] Build successful" -ForegroundColor Green
Write-Host ""

# Deploy DLLs
Write-Host "[5/6] Deploying dependencies..." -ForegroundColor Yellow
$BinDir = "$BuildDir/bin/Release"

# Copy SDL2
$SdlDll = "$SdlPath/lib/x64/SDL2.dll"
if (Test-Path $SdlDll) {
    Copy-Item -Path $SdlDll -Destination $BinDir -Force
    Write-Host "  [OK] Copied SDL2.dll" -ForegroundColor Green
}

# Copy CUDA DLLs if needed
if ($UseGPU -and $GPUBackend -eq "cuda") {
    Write-Host "  Deploying CUDA runtime DLLs..." -ForegroundColor Cyan
    
    # Find CUDA installation
    $cudaPath = $env:CUDA_PATH
    if (!$cudaPath) {
        $cudaDir = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA"
        $versions = Get-ChildItem $cudaDir -Directory -ErrorAction SilentlyContinue | Sort-Object Name -Descending
        if ($versions.Count -gt 0) {
            $cudaPath = $versions[0].FullName
        }
    }
    
    if ($cudaPath) {
        # CUDA 13.0 / 12.x DLLs
        $CudaDlls = @("cudart64_*.dll", "cublas64_*.dll", "cublasLt64_*.dll", "cudnn64_*.dll", "cufft64_*.dll")
        foreach ($pattern in $CudaDlls) {
            # Check bin root
            $dll = Get-ChildItem "$cudaPath\bin\$pattern" -ErrorAction SilentlyContinue | Select-Object -First 1
            
            # Check bin/x64 (CUDA 13 layout)
            if (!$dll) {
                $dll = Get-ChildItem "$cudaPath\bin\x64\$pattern" -ErrorAction SilentlyContinue | Select-Object -First 1
            }

            if ($dll) {
                Copy-Item -Path $dll.FullName -Destination $BinDir -Force
                Write-Host "  [OK] Copied $($dll.Name)" -ForegroundColor Green
            }
        }
        
        # Also copy from system if available (for CUDA 13)
        $systemCuda = "C:\Windows\System32\cudart64_*.dll"
        $sysDll = Get-ChildItem $systemCuda -ErrorAction SilentlyContinue | Select-Object -First 1
        if ($sysDll -and !(Test-Path "$BinDir\cudart64_*.dll")) {
            Copy-Item -Path $sysDll.FullName -Destination $BinDir -Force
            Write-Host "  [OK] Copied system $($sysDll.Name)" -ForegroundColor Green
        }
    } else {
        Write-Host "  [WARN] Could not find CUDA installation for DLL deployment" -ForegroundColor Yellow
    }
}

# Copy ggml DLLs
$GgmlDlls = Get-ChildItem "$BuildDir" -Recurse -Filter "ggml*.dll" -ErrorAction SilentlyContinue
foreach ($dll in $GgmlDlls) {
    if ($dll.FullName -like "*Release*" -or $dll.FullName -like "*bin*") {
        Copy-Item -Path $dll.FullName -Destination $BinDir -Force -ErrorAction SilentlyContinue
    }
}

Write-Host ""

# Download models
Write-Host "[6/6] Checking Whisper models..." -ForegroundColor Yellow

if (-not (Test-Path "$BinDir/models")) { 
    New-Item -ItemType Directory -Path "$BinDir/models" | Out-Null 
}

# Download tiny.en for CPU-only systems (faster, smaller)
$TinyModelName = "ggml-tiny.en.bin"
$TinyModelSrc = "$RepoRoot/models/$TinyModelName"
$TinyModelDest = "$BinDir/models/$TinyModelName"

if (-not (Test-Path $TinyModelSrc)) {
    Write-Host "  Downloading tiny.en model (for CPU-only systems)..." -ForegroundColor Cyan
    
    $DownloadScript = "$RepoRoot/models/download-ggml-model.sh"
    if (Test-Path $DownloadScript) {
        # Try bash if available
        $bash = Get-Command bash -ErrorAction SilentlyContinue
        if ($bash) {
            & bash $DownloadScript tiny.en
        } else {
            # Direct download
            $TinyModelUrl = "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin"
            Invoke-WebRequest -Uri $TinyModelUrl -OutFile $TinyModelSrc
        }
    }
}

if (Test-Path $TinyModelSrc) { 
    Copy-Item -Path $TinyModelSrc -Destination $TinyModelDest -Force
    Write-Host "  [OK] tiny.en model ready" -ForegroundColor Green
} else {
    Write-Host "  [WARN] Could not download tiny.en model" -ForegroundColor Yellow
}

# Download base.en for GPU systems (better accuracy)
$BaseModelName = "ggml-base.en.bin"
$BaseModelSrc = "$RepoRoot/models/$BaseModelName"
$BaseModelDest = "$BinDir/models/$BaseModelName"

if (-not (Test-Path $BaseModelSrc)) {
    Write-Host "  Downloading base.en model (for GPU systems)..." -ForegroundColor Cyan
    
    $DownloadScript = "$RepoRoot/models/download-ggml-model.sh"
    if (Test-Path $DownloadScript) {
        # Try bash if available
        $bash = Get-Command bash -ErrorAction SilentlyContinue
        if ($bash) {
            & bash $DownloadScript base.en
        } else {
            # Direct download
            $BaseModelUrl = "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin"
            Invoke-WebRequest -Uri $BaseModelUrl -OutFile $BaseModelSrc
        }
    }
}

if (Test-Path $BaseModelSrc) { 
    Copy-Item -Path $BaseModelSrc -Destination $BaseModelDest -Force
    Write-Host "  [OK] base.en model ready" -ForegroundColor Green
} else {
    Write-Host "  [WARN] Could not download base.en model" -ForegroundColor Yellow
    Write-Host "  Please download manually from:" -ForegroundColor Yellow
    Write-Host "  https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin" -ForegroundColor Gray
    Write-Host "  And place it in: $BaseModelDest" -ForegroundColor Gray
}

Write-Host "  [INFO] App will auto-select optimal model based on GPU availability" -ForegroundColor Cyan

Write-Host ""
Write-Host "=== Build Complete ===" -ForegroundColor Green
Write-Host ""
Write-Host "Configuration:" -ForegroundColor Cyan
Write-Host "  - GPU Backend: " -NoNewline
if ($UseGPU) {
    Write-Host "$GPUBackend" -ForegroundColor Green
} else {
    Write-Host "CPU-only" -ForegroundColor Yellow
}
Write-Host "  - CPU Threads: $env:NUMBER_OF_PROCESSORS" -ForegroundColor Cyan
Write-Host "  - Model: base.en" -ForegroundColor Cyan
Write-Host ""
Write-Host "Run the application:" -ForegroundColor White
Write-Host "  $BinDir\win-dictation.exe" -ForegroundColor Yellow
Write-Host ""
Write-Host "Hotkey: Ctrl+Shift+R to toggle recording" -ForegroundColor Gray
Write-Host ""
