# Spustí ve VM skript pro její konfiguraci
# Do VM musí být připojeno GPU

param(
    [Parameter(Mandatory = $true)]
    [string]$VMName,
    [Parameter(Mandatory = $true)]
    [string]$VMSystemVHDxPath,
    [Parameter(Mandatory = $true)]
    [string]$AdminPassword,
    [Parameter(Mandatory = $true)]
    [string]$computerName,
    [Parameter(Mandatory = $true)]
    [string]$logFile
)

$password = ConvertTo-SecureString $AdminPassword -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("Administrator", $password)

# winget is not detected via PSRemoting; this is a workaround
$wingetVersion = Invoke-Command -VMName $VMName -Credential $cred -ScriptBlock {
    $ResolveWingetPath = Resolve-Path "C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_*_x64__8wekyb3d8bbwe"
    $WingetPath = $ResolveWingetPath[-1].Path
    Set-Location $WingetPath

    winget -v
}

Write-Log -Message "Winget version: $wingetVersion" -LEVEL INFO -Log $logFile

# Main part - install all programs
$executionQueue = @(
    "Rename-Computer -NewName $computerName",
    # initial setup
    'New-Item -Path ''C:\AOFG\Autorun'' -ItemType Directory| Out-Null',
    'New-Item -Path ''C:\ProgramData\Parsec'' -ItemType Directory | Out-Null',
    'New-Item -Path ''C:\AOFG\GamesDisk'' -ItemType Directory | Out-Null',
    'Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope LocalMachine -Force',

    # Install Winget Packages
    'winget install --id=Microsoft.VCRedist.2010.x64 -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Microsoft.VCRedist.2012.x86 -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Microsoft.VCRedist.2015+.x64 -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Microsoft.VCRedist.2013.x64 -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Microsoft.VCRedist.2013.x86 -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Microsoft.VCRedist.2015+.x86 -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Microsoft.VCRedist.2012.x64 -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Microsoft.VCRedist.2010.x86 -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Microsoft.VCRedist.2005.x64 -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Microsoft.VCRedist.2008.x64 -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Microsoft.VCRedist.2008.x86 -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Valve.Steam -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=EpicGames.EpicGamesLauncher -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=7zip.7zip -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=AutoHotkey.AutoHotkey -e -h --accept-source-agreements --accept-package-agreements',
    'winget install --id=Guru3D.Afterburner -e -h --accept-source-agreements --accept-package-agreements',

    # disable the gamer from shutting down the VM via GUI
    'Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\PolicyManager\default\Start\HideShutDown" -Name "value" -Value 1', 

    # install and configure other apps and settings
    'Start-Process -FilePath ''C:\Program Files (x86)\Epic Games\Launcher\Portal\Binaries\Win32\EpicGamesLauncher.exe''',

    # Never turn off the screen
    'powercfg /setacvalueindex SCHEME_CURRENT SUB_VIDEO VIDEOIDLE 0',
    'powercfg /setdcvalueindex SCHEME_CURRENT SUB_VIDEO VIDEOIDLE 0',
    'powercfg /setactive SCHEME_CURRENT',

    # Run scripts and commands
    '& .\DownloadNvidiaDriver.ps1',
    '& .\UpdateSteamAndEpic.ps1',
    '& .\InstallParsec.ps1',
    '& .\ApplyPersonalizationSettings.ps1',
    '& .\DisablePasswordSecurityRequirements.ps1',
    'Start-Process -FilePath ''C:\Program Files\Parsec\parsecd.exe''',
    '& .\InstallAlwaysOnDisplay.ps1',
    '& .\InstallVBCable.ps1',
    '& .\CopyFiles.ps1',
    '& .\DownloadLegacyDirectXlibs.ps1',
    'Start-Process -FilePath ''C:\Program Files (x86)\RivaTuner Statistics Server\RTSS.exe''',
    'Start-Process -FilePath ''C:\Program Files (x86)\MSI Afterburner\MSIAfterburner.exe''',
    '& .\InstallPsUtilities.ps1',
    '& .\InstallWindowsUpdates.ps1',
    '& .\UninstallWindowsDefender.ps1'
    '& .\MiscWindowsSettings.ps1',
    '& .\DoNotOpenServerManager.ps1',
    '& .\DoNotSendTelemetry.ps1',
    '& .\ConfigureMSEdge.ps1',
    '& .\DiskCleanup.ps1',

    # Cleanup
    "Get-Item -Path 'C:\Users\$env:Username\Downloads' | Remove-Item -Recurse -ErrorAction SilentlyContinue",
    "Get-Item -Path 'C:\AOFG\DirectX' | Remove-Item -Recurse -ErrorAction SilentlyContinue"
)

$vmBuildFileLocation = "C:\AOFG\build\VM"
# Iterate over the execution queue and execute each item
foreach ($command in $executionQueue) {
    Write-Log -Message "<== Executing command '$command' ==>" -LEVEL INFO -Log $logFile
    $invokeCommandLog = Invoke-Command -VMName $VMName -Credential $cred -ScriptBlock {
        param($vmBuildFileLocation, $commandText)
        Set-Location $vmBuildFileLocation
        powershell -command $commandText
    } -ArgumentList $vmBuildFileLocation, $command
    
    if($invokeCommandLog) 
    {
        Write-Log -Message ($invokeCommandLog -join "`n") -LEVEL INFO -Log $logFile
    }
    Write-Log -Message "</== Finished executing command ==>" -LEVEL INFO -Log $logFile
}

$updateWaitTime = 600 # seconds
Write-Log -Message "Restarting VM, then waiting for Windows Updates to finish for $updateWaitTime seconds" -LEVEL INFO -Log $LogFile
Stop-VM -VMName $VMName
Start-VM -VMName $VMName
Start-Sleep -Seconds $updateWaitTime

Write-Log -Message "Cleaning up" -LEVEL INFO -Log $LogFile
# Secondary part - disable HyperV Display, cleanup
Invoke-Command -VMName $VMName -Credential $cred -ScriptBlock {
    param($vmBuildFileLocation)
    Set-Location $vmBuildFileLocation
    ./SuppressWindowsUpdates.ps1
    Get-Item -Path 'C:\AOFG\build' | Remove-Item -Recurse -ErrorAction SilentlyContinue
    # Disable startup of EpicGamesLauncher - to recognize preinstalled games, the EGL must not launch on startup before the games disk is connected
    Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "EpicGamesLauncher"
    Remove-Item -Path "C:\AOFG\Autorun\StartEGS.ps1"
    # DisableHyperVdisplay.ahk has (hopefully) run successfully within $sleepTime, so delete it
    Remove-Item -Path "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\DisableHyperVdisplay.ahk" -Force
    Remove-Item -Path "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\OCR.ahk" -Force

    # remove powershell history
    wevtutil clear-log "Microsoft-Windows-PowerShell/Operational"
} -ArgumentList $vmBuildFileLocation

Write-Log -Message "Stopping VM" -LEVEL INFO -Log $LogFile
Stop-VM -VMName $VMName
Write-Log -Message "Compacting VM disk" -LEVEL INFO -Log $LogFile
$sizeBeforeOptimization = (Get-ChildItem $VMSystemVHDxPath).Length / 1MB
Optimize-VHD -Path $VMSystemVHDxPath -Mode Full -ErrorAction Stop
$sizeAfterOptimization = (Get-ChildItem $VMSystemVHDxPath).Length / 1MB
Write-Log -Message "Before: $sizeBeforeOptimization MB | After: $sizeAfterOptimization MB" -LEVEL INFO -Log $LogFile
