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

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

if ([string]::IsNullOrWhiteSpace($PSScriptRoot)) {
    throw 'Run Install-Free2Csv.ps1 as a script file from the extracted package. Do not paste its contents into a PowerShell prompt.'
}

function Assert-SafeInstallDirectory {
    param([Parameter(Mandatory)][string]$Path)

    $programsRoot = [IO.Path]::GetFullPath((Join-Path $env:LOCALAPPDATA 'Programs'))
    $resolved = [IO.Path]::GetFullPath($Path)
    $prefix = $programsRoot.TrimEnd([IO.Path]::DirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar
    if (-not $resolved.StartsWith($prefix, [StringComparison]::OrdinalIgnoreCase)) {
        throw "InstallDirectory must be inside $programsRoot."
    }

    return $resolved.TrimEnd([IO.Path]::DirectorySeparatorChar)
}

$packageRoot = [IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..'))
$sourceRoot = Join-Path $packageRoot 'app'
$sourceExe = Join-Path $sourceRoot 'Free2Csv.exe'
$sourceVersionFile = Join-Path $packageRoot 'VERSION.txt'
if (-not (Test-Path -LiteralPath $sourceExe -PathType Leaf)) {
    throw "Free2Csv.exe was not found in the package app folder. Extract the full release ZIP first."
}
if (-not (Test-Path -LiteralPath $sourceVersionFile -PathType Leaf)) {
    throw 'VERSION.txt was not found. Extract the full release ZIP first.'
}

$packageVersion = (Get-Content -LiteralPath $sourceVersionFile -Raw).Trim()
if ($packageVersion -notmatch '^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$') {
    throw "The package version is invalid: '$packageVersion'."
}

$installRoot = Assert-SafeInstallDirectory -Path $InstallDirectory
$installedExe = Join-Path $installRoot 'Free2Csv.exe'
$installedUninstaller = Join-Path $installRoot 'Uninstall-Free2Csv.ps1'
$installedTester = Join-Path $installRoot 'Test-Free2CsvInstallation.ps1'
$installedVersionFile = Join-Path $installRoot 'VERSION.txt'
$ownershipMarker = Join-Path $installRoot '.free2csv-install.json'

if (Test-Path -LiteralPath $installRoot -PathType Container) {
    $existingItems = @(Get-ChildItem -LiteralPath $installRoot -Force)
    if ($existingItems.Count -gt 0) {
        if (-not (Test-Path -LiteralPath $ownershipMarker -PathType Leaf)) {
            throw "The install directory already contains files not proven to be owned by Free2 CSV: $installRoot"
        }

        $existingMarker = Get-Content -LiteralPath $ownershipMarker -Raw | ConvertFrom-Json
        if ($existingMarker.productId -ne 'Free2Csv' -or
            [IO.Path]::GetFullPath([string]$existingMarker.installDirectory) -ne $installRoot) {
            throw "The existing ownership marker is invalid for $installRoot."
        }
    }
}

New-Item -ItemType Directory -Path $installRoot -Force | Out-Null
Copy-Item -Path (Join-Path $sourceRoot '*') -Destination $installRoot -Recurse -Force
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'Uninstall-Free2Csv.ps1') -Destination $installedUninstaller -Force
Copy-Item -LiteralPath (Join-Path $PSScriptRoot 'Test-Free2CsvInstallation.ps1') -Destination $installedTester -Force
Copy-Item -LiteralPath $sourceVersionFile -Destination $installedVersionFile -Force
if (Test-Path -LiteralPath (Join-Path $packageRoot 'README.txt')) {
    Copy-Item -LiteralPath (Join-Path $packageRoot 'README.txt') -Destination (Join-Path $installRoot 'README.txt') -Force
}

$marker = [ordered]@{
    productId = 'Free2Csv'
    productName = 'Free2 CSV'
    version = $packageVersion
    installDirectory = $installRoot
}
$marker | ConvertTo-Json | Set-Content -LiteralPath $ownershipMarker -Encoding UTF8

$classesRoot = 'HKCU:\Software\Classes'
$progId = 'Free2Csv.csv'
$progIdRoot = Join-Path $classesRoot $progId
$progIdCommand = Join-Path $progIdRoot 'shell\open\command'
$progIdIcon = Join-Path $progIdRoot 'DefaultIcon'
$applicationRoot = Join-Path $classesRoot 'Applications\Free2Csv.exe'
$applicationCommand = Join-Path $applicationRoot 'shell\open\command'
$openWithProgIds = Join-Path $classesRoot '.csv\OpenWithProgids'
$capabilitiesRoot = 'HKCU:\Software\Free2Csv\Capabilities'
$fileAssociations = Join-Path $capabilitiesRoot 'FileAssociations'
$registeredApplications = 'HKCU:\Software\RegisteredApplications'
$uninstallRoot = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\Free2Csv'
$openCommand = '"{0}" "%1"' -f $installedExe

New-Item -Path $progIdCommand -Force | Out-Null
New-Item -Path $progIdIcon -Force | Out-Null
Set-Item -LiteralPath $progIdRoot -Value 'Free2 CSV document'
Set-Item -LiteralPath $progIdIcon -Value ('"{0}",0' -f $installedExe)
Set-Item -LiteralPath $progIdCommand -Value $openCommand

New-Item -Path $openWithProgIds -Force | Out-Null
New-ItemProperty -Path $openWithProgIds -Name $progId -PropertyType String -Value '' -Force | Out-Null

New-Item -Path $applicationCommand -Force | Out-Null
New-Item -Path (Join-Path $applicationRoot 'SupportedTypes') -Force | Out-Null
New-ItemProperty -Path $applicationRoot -Name 'FriendlyAppName' -PropertyType String -Value 'Free2 CSV' -Force | Out-Null
New-ItemProperty -Path (Join-Path $applicationRoot 'SupportedTypes') -Name '.csv' -PropertyType String -Value '' -Force | Out-Null
Set-Item -LiteralPath $applicationCommand -Value $openCommand

New-Item -Path $fileAssociations -Force | Out-Null
New-ItemProperty -Path $capabilitiesRoot -Name 'ApplicationName' -PropertyType String -Value 'Free2 CSV' -Force | Out-Null
New-ItemProperty -Path $capabilitiesRoot -Name 'ApplicationDescription' -PropertyType String -Value 'A clean, read-only CSV viewer for Windows.' -Force | Out-Null
New-ItemProperty -Path $fileAssociations -Name '.csv' -PropertyType String -Value $progId -Force | Out-Null
New-Item -Path $registeredApplications -Force | Out-Null
New-ItemProperty -Path $registeredApplications -Name 'Free2 CSV' -PropertyType String -Value 'Software\Free2Csv\Capabilities' -Force | Out-Null

New-Item -Path $uninstallRoot -Force | Out-Null
$powershellPath = (Get-Command powershell.exe -ErrorAction Stop).Source
$uninstallCommand = '"{0}" -NoProfile -ExecutionPolicy Bypass -File "{1}"' -f $powershellPath, $installedUninstaller
New-ItemProperty -Path $uninstallRoot -Name 'DisplayName' -PropertyType String -Value 'Free2 CSV' -Force | Out-Null
New-ItemProperty -Path $uninstallRoot -Name 'DisplayVersion' -PropertyType String -Value $packageVersion -Force | Out-Null
New-ItemProperty -Path $uninstallRoot -Name 'Publisher' -PropertyType String -Value 'Free2 CSV' -Force | Out-Null
New-ItemProperty -Path $uninstallRoot -Name 'InstallLocation' -PropertyType String -Value $installRoot -Force | Out-Null
New-ItemProperty -Path $uninstallRoot -Name 'DisplayIcon' -PropertyType String -Value $installedExe -Force | Out-Null
New-ItemProperty -Path $uninstallRoot -Name 'UninstallString' -PropertyType String -Value $uninstallCommand -Force | Out-Null
New-ItemProperty -Path $uninstallRoot -Name 'NoModify' -PropertyType DWord -Value 1 -Force | Out-Null
New-ItemProperty -Path $uninstallRoot -Name 'NoRepair' -PropertyType DWord -Value 1 -Force | Out-Null

$startMenuRoot = Join-Path $env:APPDATA 'Microsoft\Windows\Start Menu\Programs'
$shortcutPath = Join-Path $startMenuRoot 'Free2 CSV.lnk'
$shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut($shortcutPath)
$shortcut.TargetPath = $installedExe
$shortcut.WorkingDirectory = $installRoot
$shortcut.Description = 'Open CSV files in Free2 CSV'
$shortcut.Save()

Write-Host "Free2 CSV installed at $installRoot"
Write-Host 'Windows now lists Free2 CSV as an available app for .csv files.'
Write-Host 'Windows requires you to choose it as the default app yourself.'

if ($OpenDefaultApps) {
    Start-Process 'ms-settings:defaultapps'
}
