function Set-AdminPassword {
    param (
        [string]$adminPassword
    )
    # Explicitly import LocalAccounts module
    Import-Module Microsoft.PowerShell.LocalAccounts -ErrorAction SilentlyContinue
    
    # Set admin password
    Get-LocalUser -Name "${admin_username}" | Set-LocalUser -Password (ConvertTo-SecureString -AsPlainText $adminPassword -Force)
    # Enable admin user
    Get-LocalUser -Name "${admin_username}" | Enable-LocalUser
}

function Configure-RDP {
    # Enable RDP
    New-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -Name "fDenyTSConnections" -Value 0 -PropertyType DWORD -Force
    # Disable NLA
    New-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name "UserAuthentication" -Value 0 -PropertyType DWORD -Force
    New-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name "SecurityLayer" -Value 1 -PropertyType DWORD -Force
    # Enable RDP through Windows Firewall
    Enable-NetFirewallRule -DisplayGroup "Remote Desktop"

    # Disable UDP. It doesn't work via `coder port-forward` and is broken due to MTU issues in Coder Connect.
    # Requires a restart to take effect. c.f. https://github.com/coder/internal/issues/608#issuecomment-2965923672
    New-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name "SelectTransport" -Value 1 -PropertyType DWORD -Force
    Restart-Service -Name "TermService" -Force
}

function Install-DevolutionsGateway {
# Define the module name and version
$moduleName = "DevolutionsGateway"
$moduleVersion = "${devolutions_gateway_version}"

# Ensure TLS 1.2 is enabled for PSGallery
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# Install the module with the specified version for all users
# This requires administrator privileges
try {
    # Install-PackageProvider is required for AWS. Need to set command to
    # terminate on failure so that try/catch actually triggers
    Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction Stop
    
    # Set PSGallery as trusted after NuGet is installed
    Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
    
    if ($moduleVersion -eq "latest" -or [string]::IsNullOrWhiteSpace($moduleVersion)) {
        Install-Module -Name $moduleName -Force
    } else {
        Install-Module -Name $moduleName -RequiredVersion $moduleVersion -Force
    }
}
catch {
    # If the first command failed, assume that we're on GCP and run
    # Install-Module only
    if ($moduleVersion -eq "latest" -or [string]::IsNullOrWhiteSpace($moduleVersion)) {
        Install-Module -Name $moduleName -Force
    } else {
        Install-Module -Name $moduleName -RequiredVersion $moduleVersion -Force
    }
}

# Construct the module path for system-wide installation
$modulePath = $null # Declare outside the loop

if ($moduleVersion -eq "latest" -or [string]::IsNullOrWhiteSpace($moduleVersion)) {
    $installedModule = Get-InstalledModule -Name $moduleName -ErrorAction SilentlyContinue
    if ($installedModule) {
        $installedVersion = $installedModule.Version.ToString()
    }
} else {
    $installedVersion = $moduleVersion
}

$paths = $env:PSModulePath -split ';'

foreach ($path in $paths) {
    $candidatePath = Join-Path -Path $path -ChildPath $moduleName
    if ($installedVersion) {
        $candidatePath = Join-Path -Path $candidatePath -ChildPath $installedVersion
    }

    $psd1Path = Join-Path -Path $candidatePath -ChildPath "$moduleName.psd1"
    if (Test-Path $psd1Path) {
        $modulePath = $psd1Path
        break
    }
}

# Import the module using the full path
Import-Module $modulePath
Install-DGatewayPackage

# Configure Devolutions Gateway
$Hostname = "localhost"
$HttpListener = New-DGatewayListener 'http://*:7171' 'http://*:7171'
$WebApp = New-DGatewayWebAppConfig -Enabled $true -Authentication None
$ConfigParams = @{
    Hostname = $Hostname
    Listeners = @($HttpListener)
    WebApp = $WebApp
}
Set-DGatewayConfig @ConfigParams
New-DGatewayProvisionerKeyPair -Force

# Configure and start the Windows service
Set-Service 'DevolutionsGateway' -StartupType 'Automatic'
Start-Service 'DevolutionsGateway'
}

function Patch-Devolutions-HTML {
$root = "C:\Program Files\Devolutions\Gateway\webapp\client"
$devolutionsHtml = "$root\index.html"
$patch = '<script defer id="coder-patch" src="coder.js"></script>'

# Always copy the file in case we change it.
@'
${patch_file_contents}
'@ | Set-Content "$root\coder.js"

# Only inject the src if we have not before.
$isPatched = Select-String -Path "$devolutionsHtml" -Pattern "$patch" -SimpleMatch
if ($isPatched -eq $null) {
    (Get-Content $devolutionsHtml).Replace('</app-root>', "</app-root>$patch") | Set-Content $devolutionsHtml
}
}

Set-AdminPassword -adminPassword "${admin_password}"
Configure-RDP
Install-DevolutionsGateway
Patch-Devolutions-HTML
