[CmdletBinding()]
param (
    [int]
    $Id
)
    
Write-Verbose -Message "Connect to vCenter" -Verbose
Connect-ITDvCenter -Credential $Secret:ndgov_svcitdvmsnapmgr

Write-Verbose -Message "Prepare variables / SQL connection based on PSU server" -Verbose
switch($UAJob.ComputerName){
    "ITDWINAUTOT1" {
        $ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
        $Database = "ITD-Systems-Automation"
        $SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_NPD"
    }
    "ITDWINAUTOP1" {
        $ServerInstance = "itdintsql22p1.nd.gov\INTSQL22P1"
        $Database = "ITD-Systems-Automation"
        $SnapshotTable = "Infra_VMware_VirtualMachine_VMSnapshots_PRD"
    }
}

# get list of All vCenter Scheduled Tasks
$si = Get-View ServiceInstance
$scheduledTaskManager = Get-View $Si.Content.ScheduledTaskManager
Write-Verbose -Message ("Gathering all scheduled tasks with AutoSnap in the task name, this will take some time")
$AllScheduledTasks = Get-View -Id $scheduledTaskManager.ScheduledTask | Where-Object { $_.Info.Name -like "AutoSnap*" }

Write-Verbose -Message "Get SQL records with status of Scheduled" -Verbose
# get list of Scheduled from database
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Scheduled'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose

switch ($PSBoundParameters.Keys) {
    Id {
        Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
        $SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
    }
}

Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Scheduled status") -Verbose
Write-Verbose -Message "Start Scheduled > Taken Loops"
ForEach ($SqlRecord in @($SqlRecords) ) {
    $Snapshot = $null
        
    Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose
    $Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue
        
    If ($Snapshot) {
        Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found.  Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ".  Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose
        Write-Verbose -Message ("Setting SQL status to Taken") -Verbose
        # if status has changed from requested to taken, update database status field
        $TakenDateTimeSql = ($Snapshot.Description | ConvertFrom-Json).Taken.ToString('yyyy/MM/dd HH:mm:ss')
        $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Taken', TakenDateTime = '" + $TakenDateTimeSql + "' WHERE ID = " + $Snapshot.Name.split('_')[1])
        Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
    }
    Else {
        Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose
        If ($SqlRecord.DateTime -lt (Get-Date)) {
            Write-Error -Message ("AutoSnap_" + $SqlRecord.Id + " not found, and its requested datetime has passed") -Verbose
            # Update SQL record to status Failed-ScheduledNotTaken
            $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-ScheduledNotTaken' WHERE ID = " + $SqlRecord.Id)
            Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
        }
    }
    Write-Verbose -Message ("End   AutoSnap_" + $SqlRecord.Id) -Verbose
}

Write-Verbose -Message "End Scheduled > Taken Loops"
$SqlRecord = $null
$SqlRecords = $null
$SqlQueryUpdate = $null

# get list of taken from database
Write-Verbose -Message "Start Taken > Expire Loops"
Write-Verbose -Message "Get SQL records with status of Taken" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Taken'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose

switch ($PSBoundParameters.Keys) {
    Id {
        Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
        $SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
    }
}

# check status of all Taken SQLRecords
Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Taken status") -Verbose
ForEach ($SqlRecord in @($SqlRecords) ) {
    $Snapshot = $null
        
    Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose
    $Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue
        
    If ($Snapshot) {
        Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found.  Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ".  Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose
        # if expired datetime is in the past, set status to expired
        If ( ($Snapshot.Description | ConvertFrom-Json).Expire -lt (Get-Date)) {
            Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " has expired.") -Verbose
            $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Expired' WHERE ID = " + $Snapshot.Name.split('_')[1])
            Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
        }
    }
    Else {
        Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose
        $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-Manual' WHERE ID = " + $SqlRecord.Id)
        Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
    }
    Write-Verbose -Message ("End   AutoSnap_" + $SqlRecord.Id) -Verbose
    $SqlRecord = $null
    $SqlRecords = $null
    $SqlQueryUpdate = $null
}

# get list of Expired from SQL database

Write-Verbose -Message "Start Expired > Removed Loops"
Write-Verbose -Message "Get SQL records with status of Expired" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Expired'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose

switch ($PSBoundParameters.Keys) {
    Id {
        Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
        $SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
    }
}

# check status of all Expired SQLRecords
Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Expired status") -Verbose
ForEach ($SqlRecord in @($SqlRecords) ) {
    $Snapshot = $null
        
    Write-Verbose -Message ("Start AutoSnap_" + $SqlRecord.Id) -Verbose
    $Snapshot = Get-VM -Name $SqlRecord.VMName | Get-Snapshot -Name ("AutoSnap_" + $SqlRecord.ID) -ErrorAction SilentlyContinue
        
    If ($Snapshot) {
        Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " found.  Taken: " + ($Snapshot.Description | ConvertFrom-Json).Taken + ".  Expire: " + ($Snapshot.Description | ConvertFrom-Json).Expire) -Verbose
        # if expired datetime is in the past, set status to expired
        If ( ($Snapshot.Description | ConvertFrom-Json).Expire -lt (Get-Date)) {
            Write-Verbose -Message ("Snapshot " + $Snapshot.Name + " is expired.  Will be removed at next Removal run") -Verbose
            #$SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Expired' WHERE ID = " + $Snapshot.Name.split('_')[1])
            #Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
        }
    }
    Else {
        Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " not found.") -Verbose
        $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Deleted-Manual' WHERE ID = " + $SqlRecord.Id)
        Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
    }
    Write-Verbose -Message ("End   AutoSnap_" + $SqlRecord.Id) -Verbose
    $SqlRecord = $null
    $SqlRecords = $null
    $SqlQueryUpdate = $null
}


# get list of requested from SQL database
Write-Verbose -Message "Start Requested > Scheduled Loops"
Write-Verbose -Message "Get SQL records with status of Requested" -Verbose
$SqlQuery = "SELECT [ID],[VMName],[DateTime],[RequestedBy],[DurationHours],[Status],[NotifyEmail],[TakenDateTime],[ExpireDateTime],[DeleteDateTime] FROM [ITD-Systems-Automation].[dbo].[$SnapshotTable] WHERE Status = 'Requested'"
$SqlRecords = Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQuery -Credential $Secret:sql_itdpsu1 -Verbose

switch ($PSBoundParameters.Keys) {
    Id {
        Write-Verbose -Message "Narrowing results to Id parameter value of $Id" -Verbose
        $SqlRecords = $SqlRecords | Where-Object Id -EQ "$Id"
    }
}

# check status of all Requested SQLRecords
Write-Verbose -Message ("Found " + @($SqlRecords).count + " snapshots with Requested status") -Verbose
ForEach ($SqlRecord in @($SqlRecords) ) {
    # does the scheduled tasks exist?
    If ($AllScheduledTasks | Where-Object { $_.Info.Name -eq ("AutoSnap_" + $SqlRecord.Id + '_' + $SqlRecord.VMName) }) {
        # yes - update SQL status to Scheduled
        Write-Verbose -Message ("AutoSnap_" + $SqlRecord.Id + " vCenter scheduled task exists.") -Verbose
        Write-Verbose -Message ("Setting SQL status to Scheduled") -Verbose
        $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Scheduled' WHERE ID = " + $SqlRecord.ID)
        Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
    }
    Else {
        # no
        # has date/time passed? (10 minute buffer)
        If ($SqlRecord.DateTime -lt (Get-Date).AddMinutes(-10)) {
            # yes - set SQL status to Failed-RequestedNotScheduled
            Write-Warning -Message ("AutoSnap_" + $SqlRecord.Id + " was not scheduled before its datetime.")
            $SqlQueryUpdate = ("UPDATE [$SnapshotTable] SET Status = 'Failed-RequestedNotScheduled' WHERE ID = " + $SqlRecord.ID)
            Invoke-Sqlcmd -ServerInstance $ServerInstance -Database $Database -Query $SqlQueryUpdate -Credential $Secret:sql_itdpsu1 -Verbose
        }
        Else {
            # no ???
        }
        Write-Error -Message ("AutoSnap_" + $SqlRecord.Id + " scheduled task does not exist.")
    }
}
Write-Verbose -Message "End Requested > Scheduled Loops"
$SqlRecord = $null
$SqlRecords = $null
$SqlQueryUpdate = $null

Disconnect-ITDvCenter
