$ErrorActionPreference = 'Stop';

Set-StrictMode -Version '2.0';

$WindowsUninstallBasePath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall';
$UninstallStringScriptPrefix = 'powershell -NonInteractive -File'

function Get-UninstallKeyPath() {
    return $WindowsUninstallBasePath;
}

function New-UninstallKey {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$UninstallId, 

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$DisplayName,

        [string]$DisplayVersion = '1.0.0',

        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$ScriptPath,

        [ValidateNotNullOrEmpty()]
        [string]$UninstallArgs = '-Uninstall'
    )

    $sourcePath = (Split-Path $ScriptPath -Parent)

#powershell -NonInteractive -File 'c:\source\ps-uninstall\script.ps1' -Uninstall

    $props = @{
        DisplayName = $displayName;
        Publisher = 'Flexera Software';
        InstallSource = $sourcePath
        UninstallString = $UninstallStringScriptPrefix + ' ' + $ScriptPath + ' ' + $UninstallArgs + ' ' + (Get-PowershellLiteralString $UninstallId)
    };

    $uninstallBasePath = Get-UninstallKeyPath
    $uninstallKeyPath = (Join-Path $uninstallBasePath $uninstallId)

    if (Test-Path $uninstallKeyPath) {
        Write-Warning -Message "Patch already installed, reinstalling: '$displayName'";

        return $false;
    }

    New-Item  -Path $uninstallBasePath -Name $uninstallId | Out-Null

    foreach ($prop in $props.GetEnumerator()) {
        #Write-Host $prop.Key $uninstallKeyPath
        New-ItemProperty -Path $uninstallKeyPath -Name $prop.Key -Value $prop.Value -PropertyType 'String' | Out-Null
    }
}

function Remove-UninstallKey {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]$UninstallId
    )

    $uninstallBasePath = Get-UninstallKeyPath
    $uninstallKeyPath = (Join-Path $uninstallBasePath $uninstallId)
    
    if (Test-Path $uninstallKeyPath) {
        Remove-Item -Recurse -Force -Path $uninstallKeyPath
    }
}

function Get-PowershellLiteralString($Candidate) {

    if ($Candidate -eq $null) {
        return '$null';
    }

    $Candidate = [string]$Candidate

    $pattern = '[\000\a\b\t\n\v\f\r`"$]'

    $evaluator = [System.Text.RegularExpressions.MatchEvaluator]`
        {
            param(
                [System.Text.RegularExpressions.Match]$match
            )

            switch ($match.Value) {
                "`0" { return '`0' }
                "`a" { return '`a' }
                "`b" { return '`b' }
                "`t" { return '`t' }
                "`n" { return '`n' }
                "`v" { return '`v' }
                "`f" { return '`f' }
                "`r" { return '`r' }
                '`'  { return '``' }
                '"'  { return '`"' }
                '$'  { return '`$' }
                Default {
                    throw 'Unknown character for escaping'
                }
            }
        };

    $Candidate = [regex]::Replace($Candidate, $pattern, $evaluator);

    return '"' + $Candidate + '"'
}