[CmdletBinding()]
param(
    [string]$InstallDirectory = (Join-Path $env:LOCALAPPDATA 'Programs\Free2 CSV')
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

$installRoot = [IO.Path]::GetFullPath($InstallDirectory)
$installedExe = Join-Path $installRoot 'Free2Csv.exe'
if (-not (Test-Path -LiteralPath $installedExe -PathType Leaf)) {
    throw "Installed executable not found at $installedExe"
}

$ownershipMarker = Join-Path $installRoot '.free2csv-install.json'
$installedVersionFile = Join-Path $installRoot 'VERSION.txt'
if (-not (Test-Path -LiteralPath $ownershipMarker -PathType Leaf)) {
    throw "The Free2 CSV ownership marker is missing from $installRoot."
}
if (-not (Test-Path -LiteralPath $installedVersionFile -PathType Leaf)) {
    throw "The Free2 CSV version file is missing from $installRoot."
}

$marker = Get-Content -LiteralPath $ownershipMarker -Raw | ConvertFrom-Json
$installedVersion = (Get-Content -LiteralPath $installedVersionFile -Raw).Trim()
if ($marker.productId -ne 'Free2Csv' -or
    [IO.Path]::GetFullPath([string]$marker.installDirectory) -ne $installRoot -or
    [string]$marker.version -ne $installedVersion) {
    throw 'The Free2 CSV ownership marker is invalid.'
}

if (-not (Test-Path -LiteralPath (Join-Path $installRoot 'wpfgfx_cor3.dll') -PathType Leaf)) {
    throw 'The installed self-contained WPF runtime files are incomplete.'
}

$expectedCommand = '"{0}" "%1"' -f $installedExe
$actualCommand = (Get-Item -LiteralPath 'HKCU:\Software\Classes\Free2Csv.csv\shell\open\command').GetValue('')
if ($actualCommand -ne $expectedCommand) {
    throw "The .csv open command is not registered correctly. Expected '$expectedCommand'; found '$actualCommand'."
}

$registeredCapability = Get-ItemPropertyValue -LiteralPath 'HKCU:\Software\RegisteredApplications' -Name 'Free2 CSV'
if ($registeredCapability -ne 'Software\Free2Csv\Capabilities') {
    throw 'Free2 CSV is not registered in Windows RegisteredApplications.'
}

$association = Get-ItemPropertyValue -LiteralPath 'HKCU:\Software\Free2Csv\Capabilities\FileAssociations' -Name '.csv'
if ($association -ne 'Free2Csv.csv') {
    throw 'The Free2 CSV capability does not advertise the .csv association.'
}

$registeredVersion = Get-ItemPropertyValue `
    -LiteralPath 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\Free2Csv' `
    -Name 'DisplayVersion'
if ($registeredVersion -ne $installedVersion) {
    throw "The registered version '$registeredVersion' does not match the installed version '$installedVersion'."
}

$openWithAssociation = Get-ItemProperty -LiteralPath 'HKCU:\Software\Classes\.csv\OpenWithProgids'
if ($null -eq $openWithAssociation.PSObject.Properties['Free2Csv.csv']) {
    throw 'Free2 CSV is not present in the per-user .csv OpenWithProgids list.'
}

$testRoot = Join-Path ([IO.Path]::GetTempPath()) ("Free2Csv-Test-{0:N}" -f [Guid]::NewGuid())
New-Item -ItemType Directory -Path $testRoot | Out-Null
$fixturePath = Join-Path $testRoot 'smoke test.csv'
try {
    $fixture = "Name,Description,URL`r`nAlpha,`"Wrapped text with a comma, and quotes `"`"inside`"`"`",https://example.com`r`nBravo,Second row,`r`n"
    [IO.File]::WriteAllText($fixturePath, $fixture, [Text.UTF8Encoding]::new($true))
    $expectedWriteTime = [DateTime]::SpecifyKind([DateTime]'2025-01-02T03:04:05', [DateTimeKind]::Utc)
    [IO.File]::SetLastWriteTimeUtc($fixturePath, $expectedWriteTime)
    $hashBefore = (Get-FileHash -LiteralPath $fixturePath -Algorithm SHA256).Hash
    $process = Start-Process -FilePath $installedExe -ArgumentList @('--self-test', ('"{0}"' -f $fixturePath)) -Wait -PassThru -WindowStyle Hidden
    if ($process.ExitCode -ne 0) {
        throw "Free2 CSV self-test failed with exit code $($process.ExitCode)."
    }

    $hashAfter = (Get-FileHash -LiteralPath $fixturePath -Algorithm SHA256).Hash
    $writeTimeAfter = [IO.File]::GetLastWriteTimeUtc($fixturePath)
    if ($hashBefore -ne $hashAfter -or $writeTimeAfter -ne $expectedWriteTime) {
        throw 'The self-test changed the source CSV.'
    }
}
finally {
    if (Test-Path -LiteralPath $testRoot) {
        Remove-Item -LiteralPath $testRoot -Recurse -Force
    }
}

Write-Host 'Free2 CSV installation verification passed.'
