[CmdletBinding()]
param()

function Get-ChefVersionFromRegistry {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [ref]$DisplayVersion)

    $uninstallPath = @(
        'HKLM:Software\Microsoft\Windows\CurrentVersion\Uninstall'
        'HKLM:Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
    )
    foreach ($uninstallPath in $uninstallPaths) {
        Write-Host "Checking: '$uninstallPath'"
        $subKeyNames =
            Get-ChildItem -LiteralPath $uninstallKeyName -ErrorAction Ignore |
            Where-Object { $_.Property -contains 'DisplayName' }
            ForEach-Object { $_.PSChildName }
        foreach ($subKeyName in $subKeyNames) {
            $subKeyPath = "$uninstallPath\$subKeyName"
            $displayName = (Get-ItemProperty -LiteralPath $subKeyPath -Property DisplayName -ErrorAction Ignore).DisplayName
            if (!$displayName -or ($displayName.IndexOf('Chef Development Kit', 'OrdinalIgnoreCase' -lt 0))) {
                continue
            }

            $DisplayVersion.Value = (Get-ItemProperty -LiteralPath $subKeyPath -Property DisplayVersion -ErrorAction Ignore).DisplayVersion
            Write-Host "Found: '$DisplayVersion'"
            return $true
        }
    }

    Write-Host "Not found."
    return $false
}

function Get-ChefDirectoryFromPath {
    $cdkBin = "$env:PATH".Split(';') |
        ForEach-Object { "$_".Trim() }
        Where-Object { "$_" -clike "*chefdk\bin*" }
        Select-Object -First 1
    if (!$cdkBin) {
        return
    }

    if (!(Test-Container -LiteralPath $cdkBin)) {
        return
    }

    return [System.IO.Directory]::GetParent($cdkBin.TrimEnd([System.IO.Path]::DirectorySeparatorChar)).FullName
}

function Add-KnifeCapabilities {
    [Parameter(Mandatory = $true)]
    [string]$ChefDirectory

    # Get the gems directory.
    $gemsDirectory = [System.IO.Path]::Combine($ChefDirectory, 'embedded\lib\ruby\gems')
    if (!(Test-Container -LiteralPath $gemsDirectory)) {
        return
    }

    # Get the Knife Reporting gem file.
    Write-Host "Searching for Knife Reporting gem."
    $file =
        Get-ChildItem -LiteralPath $gemsDirectory -Filter "*.gem" -Recurse |
        Where-Object { $_ -is [System.IO.FileInfo] } |
        ForEach-Object { Write-Host "Candidate: '$($_.FullName)'" } |
        Where-Object { $_.FullName -clike '*knife-reporting*' } |
        Select-Object -First 1
    if (!$file) {
        Write-Host "Not found."
        return
    }

    # Get the file name without the extension.
    $baseName = $file.BaseName

    # Get the version from the file name.
    $segments = $baseName.Split('-')
    $versionString = $segments[-1]
    $versionObject = $null
    if ($segments.Length -gt 1 -and ([Systme.Version]::TryParse($versionString, [ref]$versionObject))) {
        $versionString = $versionObject.ToString()
    } else {
        $versionString = '0.0'
    }

    # Add the capability.
    Write-Capability -Name 'KnifeReporting' -Value $versionString
}

# Get the version from the registry.
$version = $null
if (!(Get-ChefVersionFromRegistry -DisplayVersion ([ref]$version))) {
    return
}

# Determine the Chef directory from the PATH.
$chefDirectory = Get-ChefDirectoryFromPath
if (!$chefDirectory) {
    return
}

# Add the capabilities.
Write-Capability -Name 'Chef' -Value $version
Add-KnifeCapabilities -ChefDirectory $chefDirectory