# tamper.ps1 - VM-side: apply each driftScenarios entry from matrix.json
# for the requested PCType/PCSubType, then print what was tampered. Used
# by the harness between cycle-1 (clean run) and cycle-2 (heal).
#
# Methods supported:
#   RegRemove        -> remove a registry value
#   RegSet           -> set a registry value to a wrong value
#   FileDelete       -> delete a file
#   FileOverwrite    -> rewrite a file with bogus content
#   FileGrepDelete   -> drop matching lines from a text file (e.g. hosts)

[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)] [string]$MatrixPath,
    [Parameter(Mandatory=$true)] [string]$PCType,
    [string]$PCSubType
)

$ErrorActionPreference = 'Continue'
$matrix = Get-Content -LiteralPath $MatrixPath -Raw | ConvertFrom-Json

# Same alias map as verify-state.ps1 so harness invocations with the new
# gea-shopfloor-* names find the correct matrix row even when that row's
# PCType field is still the legacy "Standard"+"Machine" form.
$pcTypeAliasGroups = @(
    @('Standard-Machine','gea-shopfloor-collections'),
    @('Standard-Machine-NoCollections','gea-shopfloor-nocollections'),
    @('Standard-Timeclock','Lab','gea-shopfloor-common'),
    @('CMM','gea-shopfloor-cmm'),
    @('Keyence','gea-shopfloor-keyence'),
    @('WaxAndTrace','gea-shopfloor-waxtrace'),
    @('Genspect','gea-shopfloor-genspect'),
    @('Display','gea-shopfloor-display'),
    @('Heattreat','gea-shopfloor-heattreat'),
    @('Shopfloor')
)
function Test-MatrixEntryMatches {
    param($Entry, [string]$Type, [string]$SubType)
    $entryKey   = if ($Entry.PCSubType) { "$($Entry.PCType)-$($Entry.PCSubType)" } else { $Entry.PCType }
    $requestKey = if ($SubType)         { "$Type-$SubType" }                       else { $Type }
    if ($entryKey -ieq $requestKey) { return $true }
    foreach ($g in $pcTypeAliasGroups) {
        if ($g -icontains $entryKey -and $g -icontains $requestKey) { return $true }
    }
    return $false
}

$entry = $matrix.pcTypes | Where-Object { Test-MatrixEntryMatches -Entry $_ -Type $PCType -SubType $PCSubType } | Select-Object -First 1
if (-not $entry) { Write-Host "[FAIL] no matrix entry for $PCType/$PCSubType"; exit 1 }

foreach ($d in $entry.driftScenarios) {
    $t = $d.tamper
    try {
        switch ($t.method) {
            'RegRemove' {
                if (Test-Path -LiteralPath $t.path) {
                    Remove-ItemProperty -LiteralPath $t.path -Name $t.regName -Force -ErrorAction Stop
                }
                Write-Host "[TAMPER] $($d.name) - removed reg $($t.path)\$($t.regName)"
            }
            'RegSet' {
                if (-not (Test-Path -LiteralPath $t.path)) {
                    New-Item -Path $t.path -Force | Out-Null
                }
                Set-ItemProperty -LiteralPath $t.path -Name $t.regName -Value $t.value -Force
                Write-Host "[TAMPER] $($d.name) - set reg $($t.path)\$($t.regName) = $($t.value)"
            }
            'FileDelete' {
                if (Test-Path -LiteralPath $t.path) { Remove-Item -LiteralPath $t.path -Force -ErrorAction Stop }
                Write-Host "[TAMPER] $($d.name) - deleted $($t.path)"
            }
            'FileOverwrite' {
                Set-Content -LiteralPath $t.path -Value $t.content -Encoding ascii -Force
                Write-Host "[TAMPER] $($d.name) - overwrote $($t.path)"
            }
            'FileGrepDelete' {
                $kept = Get-Content -LiteralPath $t.path | Where-Object { $_ -notmatch $t.pattern }
                Set-Content -LiteralPath $t.path -Value $kept -Encoding ascii -Force
                Write-Host "[TAMPER] $($d.name) - dropped lines matching $($t.pattern) from $($t.path)"
            }
            default { Write-Host "[WARN] unknown tamper method: $($t.method)" }
        }
    } catch {
        Write-Host "[WARN] tamper failed for $($d.name): $_"
    }
}
