#Requires -Version 7.4

function Test-vSEALRegistryValue {
    <#
    .SYNOPSIS
        Tests if a registry value exists.

    .DESCRIPTION
        Checks whether a specific registry value exists in a given key.
        Supports WOW6432Node redirection and user-specific registry access via SID.
        Uses Convert-vSEALRegistryPath internally for path normalization.

    .PARAMETER Key
        The registry key path (e.g., HKLM:\SOFTWARE\Microsoft).

    .PARAMETER Name
        The name of the registry value to test for. Can be any object type for flexibility.

    .PARAMETER Wow6432Node
        Access the 32-bit registry view on 64-bit systems.

    .PARAMETER SID
        User SID for accessing user-specific registry (converts HKCU to HKU\SID).

    .OUTPUTS
        [bool] $true if the value exists, $false otherwise.

    .EXAMPLE
        Test-vSEALRegistryValue -Key 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion' -Name 'ProgramFilesDir'
        Returns $true if the value exists.

    .EXAMPLE
        Test-vSEALRegistryValue -Key 'HKLM:\SOFTWARE\Test' -Name 'Setting' -Wow6432Node
        Checks the 32-bit registry view.

    .EXAMPLE
        Test-vSEALRegistryValue -Key 'HKCU:\Software\Test' -Name 'Setting' -SID 'S-1-5-21-123456789'
        Checks another user's registry hive.

    .EXAMPLE
        'HKLM:\SOFTWARE\Test' | Test-vSEALRegistryValue -Name 'Setting'
        Pipeline input for the Key parameter.
    #>
    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [Parameter(Mandatory, Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [ValidateNotNullOrEmpty()]
        [string]$Key,

        [Parameter(Mandatory, Position = 1, ValueFromPipelineByPropertyName)]
        [ValidateNotNull()]
        [object]$Name,

        [Parameter(Position = 2)]
        [switch]$Wow6432Node,

        [Parameter()]
        [string]$SID
    )

    process {
        # Convert Name to string if it's not already
        $nameString = if ($Name -is [string]) { $Name } else { $Name.ToString() }

        # Convert the registry path using the helper function
        $convertParams = @{
            Key = $Key
        }
        if ($Wow6432Node) {
            $convertParams['Wow6432Node'] = $true
        }
        if ($SID) {
            $convertParams['SID'] = $SID
        }

        try {
            $convertedPath = Convert-vSEALRegistryPath @convertParams
        }
        catch {
            Write-vSEALLog -Message "Failed to convert registry path '$Key': $($_.Exception.Message)" -Level 'ERROR'
            return $false
        }

        Write-vSEALLog -Message "Testing for registry value: $convertedPath\$nameString" -Level 'VERBOSE'

        # Check if the key exists
        if (-not (Test-Path -LiteralPath $convertedPath)) {
            Write-vSEALLog -Message "Registry key does not exist: $convertedPath" -Level 'VERBOSE'
            return $false
        }

        # Check if the value exists
        try {
            $null = Get-ItemProperty -LiteralPath $convertedPath -Name $nameString -ErrorAction Stop
            Write-vSEALLog -Message "Registry value exists: $convertedPath\$nameString" -Level 'VERBOSE'
            return $true
        }
        catch [System.Management.Automation.ItemNotFoundException] {
            Write-vSEALLog -Message "Registry value not found: $convertedPath\$nameString" -Level 'VERBOSE'
            return $false
        }
        catch [System.Management.Automation.PSArgumentException] {
            Write-vSEALLog -Message "Registry value not found: $convertedPath\$nameString" -Level 'VERBOSE'
            return $false
        }
        catch {
            Write-vSEALLog -Message "Error testing registry value '$convertedPath\$nameString': $($_.Exception.Message)" -Level 'ERROR'
            return $false
        }
    }
}
