param (
    [Parameter(Mandatory = $true)]
    [string]$vmPath,
    [Parameter(Mandatory = $true)]
    [string]$vmName
)

Set-Location $PSScriptRoot


#Include common functions
#VMC spojuje skript a AOF Library "textove" a vysledek pak vola jako jeden cely skript - ridi se touto znackou:
#<VMC-Include-AOFLibrary>
#Pri debugovani includujeme AOFLibrary standardnim zpusobem
.($PSScriptRoot+"\AOFLibrary.ps1")

#variables
$ScriptName = "DeleteVM"
$LogFile = BeginScriptLogging -ScriptName $ScriptName

$MaxDeleteAttempts = 100

$VMToDelete = Get-VM -Name "$vmName" -ErrorAction SilentlyContinue -ErrorVariable gVM
if ($gvm) {
    HandleScriptExecutionError -Message "Failed to retrieve VM '$vmName'`r`nError: $gVM" -Log $LogFile
}

$VMFolder = Join-Path $vmPath $vmName
if(-not (Test-Path -Path $VMFolder -PathType Container))
{
    HandleScriptExecutionError -Message "VM Folder $VMFolder doesn't exist`r`n" -Log $LogFile 
}

Write-Log -Message "Deleting VM '$($VMToDelete.Name)'" -Level DEBUG -Log $LogFile
#turn off the VM
Stop-VM -VM $VMToDelete -TurnOff -ErrorAction SilentlyContinue -ErrorVariable stpVM
if ($stpVM) {
    HandleScriptExecutionError -Message "Failed to stop VM '$vmName'`r`nError: $stpVM" -Log $LogFile
}

# Unassign all assigned devices before deleting the VM
$assignedDevices = Get-VMAssignableDevice -VM $VMToDelete
if ($assignedDevices) 
{
    Write-Log "VM Contains assigned devices, attempting to unsassign them" -Level WARN -Log $LogFile
    foreach ($device in $assignedDevices) 
    {
        # $device.InstanceID starts with PCIP\ and not PCI\, which cannot be used to enable the device
        $instanceId = Get-GpuInstanceId -GpuLocationPath $device.LocationPath

        try 
        {
            # -VM $VMToDelete does not work for whatever reason
            Remove-VMAssignableDevice -LocationPath $device.LocationPath -VMName $VMToDelete.Name -Verbose
            Mount-VMHostAssignableDevice -LocationPath $device.LocationPath -Verbose
            Enable-PnpDevice -InstanceId $instanceId -Confirm:$false -ErrorAction Stop -Verbose
        }
        catch 
        {
            HandleScriptExecutionError -Message "Unable to remove assigned device at $($device.LocationPath) from $VMToDelete" -Log $LogFile
        }
    }
}

#delete the VM
Remove-VM -VM $VMToDelete -Force -Confirm:$false -ErrorAction Stop -ErrorVariable dVM
if ($dVM) {
    HandleScriptExecutionError -Message "Failed to delete VM '$vmName'`r`nError: $dVM" -Log $LogFile
}

Write-Log -Message "Successfully deleted VM '$vmName' from Hyper-V" -Level INFO -Log $LogFile
#remove the folders of the deleted VMs (Remove-VM doesn't delete vitual disks)
#done in a loop, since Hyper-V will be merging checkpoints after VMs are removed and the files are locked before this is finished
$Repetitions = 0
do {
    Remove-Item -Path $VMFolder -Recurse -Confirm:$false -Force
    Start-Sleep -Seconds 5
    $Repetitions++
} while ((Get-ChildItem -Path $vmPath -Directory | Where-Object { $_.Name -like "$vmName" }) -and ($Repetitions -le $MaxDeleteAttempts))
if ($Repetitions -gt $MaxDeleteAttempts) {
    HandleScriptExecutionError -Message "Failed to delete VM folder" -Log $LogFile
} else {        
    Write-Log -Message "Successfully deleted VM folder '$VMFolder'" -Level INFO -Log $LogFile
}

Write-ScriptSuccess -Log $LogFile
