[CmdletBinding()]
param(
    [switch]$StartNow,
    [switch]$ShowNow,
    [switch]$NoAutoStart,
    [string]$InstallDir = (Join-Path $env:ProgramFiles 'KIM Quest Remote')
)

$ErrorActionPreference = 'Stop'
$BundleRoot = (Resolve-Path -LiteralPath (Split-Path -Parent $MyInvocation.MyCommand.Path)).Path
$SourceExe = Join-Path $BundleRoot 'KIMQuestRemoteHost.exe'
$SourcePatcher = Join-Path $BundleRoot 'KIMRemotePatcher.ps1'
$IsAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
    [Security.Principal.WindowsBuiltInRole]::Administrator
)

if (-not $IsAdmin) {
    throw 'Run this installer from a PowerShell window opened with Run as administrator.'
}
if (-not (Test-Path -LiteralPath $SourceExe)) {
    throw "KIMQuestRemoteHost.exe was not found beside this installer: $BundleRoot"
}
if (-not (Test-Path -LiteralPath $SourcePatcher)) {
    throw "KIMRemotePatcher.ps1 was not found beside this installer: $BundleRoot"
}

$InstallDir = [System.IO.Path]::GetFullPath($InstallDir)
$TargetExe = Join-Path $InstallDir 'KIMQuestRemoteHost.exe'
$ExpectedHash = (Get-FileHash -LiteralPath $SourceExe -Algorithm SHA256).Hash

$Running = @(
    Get-CimInstance Win32_Process -Filter "Name='KIMQuestRemoteHost.exe'" -ErrorAction SilentlyContinue
)
foreach ($Process in $Running) {
    Stop-Process -Id $Process.ProcessId -Force -ErrorAction Stop
}

New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
$PreviousExe = Join-Path $InstallDir 'KIMQuestRemoteHost.previous.exe'
if (Test-Path -LiteralPath $TargetExe) {
    Copy-Item -LiteralPath $TargetExe -Destination $PreviousExe -Force
}
$TempExe = Join-Path $InstallDir 'KIMQuestRemoteHost.exe.new'
Copy-Item -LiteralPath $SourceExe -Destination $TempExe -Force
if ((Get-FileHash -LiteralPath $TempExe -Algorithm SHA256).Hash -ne $ExpectedHash) {
    throw 'The installed EXE copy failed SHA-256 verification.'
}
Move-Item -LiteralPath $TempExe -Destination $TargetExe -Force
Copy-Item -LiteralPath $SourcePatcher -Destination (Join-Path $InstallDir 'KIMRemotePatcher.ps1') -Force

foreach ($OptionalName in @('KIMQuestRemote.apk', 'KIMQuestRemote-update.json')) {
    $OptionalSource = Join-Path $BundleRoot $OptionalName
    if (Test-Path -LiteralPath $OptionalSource) {
        Copy-Item -LiteralPath $OptionalSource -Destination (Join-Path $InstallDir $OptionalName) -Force
    }
}

$Shell = New-Object -ComObject WScript.Shell
function Set-KIMShortcut {
    param(
        [Parameter(Mandatory)]
        [string]$Path,
        [Parameter(Mandatory)]
        [string]$Arguments,
        [Parameter(Mandatory)]
        [string]$Description
    )
    $Shortcut = $Shell.CreateShortcut($Path)
    $Shortcut.TargetPath = $TargetExe
    $Shortcut.Arguments = $Arguments
    $Shortcut.WorkingDirectory = $InstallDir
    $Shortcut.IconLocation = "$TargetExe,0"
    $Shortcut.Description = $Description
    $Shortcut.Save()
}

$DesktopShortcut = Join-Path ([Environment]::GetFolderPath('Desktop')) 'KIM Remote.lnk'
Set-KIMShortcut -Path $DesktopShortcut -Arguments '--show' -Description 'Open KIM private remote desktop'

$StartupShortcut = Join-Path ([Environment]::GetFolderPath('Startup')) 'KIM Remote.lnk'
$LegacyStartupShortcut = Join-Path ([Environment]::GetFolderPath('Startup')) 'KIM Quest Remote.lnk'
Remove-Item -LiteralPath $LegacyStartupShortcut -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $StartupShortcut -Force -ErrorAction SilentlyContinue
$PatchTaskName = 'KIM Remote Auto Patcher'
if ($NoAutoStart) {
    Unregister-ScheduledTask -TaskName $PatchTaskName -Confirm:$false -ErrorAction SilentlyContinue
} else {
    $PowerShell = Join-Path $env:SystemRoot 'System32\WindowsPowerShell\v1.0\powershell.exe'
    $Patcher = Join-Path $InstallDir 'KIMRemotePatcher.ps1'
    $TaskArguments = "-NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File `"$Patcher`""
    $Action = New-ScheduledTaskAction -Execute $PowerShell -Argument $TaskArguments
    $Trigger = New-ScheduledTaskTrigger -AtLogOn -User ([Security.Principal.WindowsIdentity]::GetCurrent().Name)
    $Principal = New-ScheduledTaskPrincipal `
        -UserId ([Security.Principal.WindowsIdentity]::GetCurrent().Name) `
        -LogonType Interactive `
        -RunLevel Highest
    $Settings = New-ScheduledTaskSettingsSet `
        -ExecutionTimeLimit (New-TimeSpan -Minutes 10) `
        -StartWhenAvailable `
        -AllowStartIfOnBatteries `
        -DontStopIfGoingOnBatteries
    Register-ScheduledTask `
        -TaskName $PatchTaskName `
        -Action $Action `
        -Trigger $Trigger `
        -Principal $Principal `
        -Settings $Settings `
        -Description 'Verify and install signed KIM Remote patches before starting the tray host.' `
        -Force | Out-Null
}

$RuleName = 'KIM Quest Remote Host'
$ExistingRule = Get-NetFirewallRule -DisplayName $RuleName -ErrorAction SilentlyContinue
if (-not $ExistingRule) {
    New-NetFirewallRule `
        -DisplayName $RuleName `
        -Direction Inbound `
        -Action Allow `
        -Protocol TCP `
        -LocalPort 45830 `
        -Profile Any `
        -RemoteAddress @('LocalSubnet', '100.64.0.0/10') | Out-Null
} else {
    $ExistingRule | Set-NetFirewallRule -Profile Any -Action Allow -Enabled True
    $ExistingRule |
        Get-NetFirewallAddressFilter |
        Set-NetFirewallAddressFilter -RemoteAddress @('LocalSubnet', '100.64.0.0/10')
}

if ($StartNow) {
    if ($NoAutoStart) {
        $Arguments = if ($ShowNow) { '--show' } else { '' }
        if ($Arguments) {
            Start-Process -FilePath $TargetExe -ArgumentList $Arguments -WorkingDirectory $InstallDir
        } else {
            Start-Process -FilePath $TargetExe -WorkingDirectory $InstallDir
        }
    } else {
        $PatcherArguments = @(
            '-NoProfile',
            '-ExecutionPolicy', 'Bypass',
            '-WindowStyle', 'Hidden',
            '-File', (Join-Path $InstallDir 'KIMRemotePatcher.ps1')
        )
        if ($ShowNow) { $PatcherArguments += '-Show' }
        Start-Process -FilePath 'powershell.exe' -ArgumentList $PatcherArguments -WindowStyle Hidden
    }
}

Write-Host 'INSTALL_PASS'
Write-Host "Installed: $TargetExe"
Write-Host "SHA256: $ExpectedHash"
Write-Host "Signed patcher before startup: $(-not $NoAutoStart)"
Write-Host 'Firewall remote scope: LocalSubnet, 100.64.0.0/10'
Write-Host 'Identity preserved/generated only under the local Windows profile.'
