#Requires -Version 7.4

function Write-vSEALStatus {
    <#
    .SYNOPSIS
        Writes vSEAL execution status to a persistent JSON file.

    .DESCRIPTION
        Persists the execution status of vSEAL Seal or Engage phases to status.json.
        Uses atomic write pattern (temp file + rename) and filesystem flush to ensure
        durability against abrupt termination (imaging, shutdown).

        Seal phase writes/overwrites seal section and clears engage section.
        Engage phase writes/overwrites engage section and preserves seal section.

        When a baseline is created during Seal phase, the BaselineId can be included
        for traceability and rollback reference.

    .PARAMETER Phase
        The execution phase: 'Seal' or 'Engage'.

    .PARAMETER Result
        The execution result: 'Success', 'PartialSuccess', or 'Failed'.

    .PARAMETER PluginsRun
        Total number of plugins that were executed.

    .PARAMETER PluginsFailed
        Number of plugins that failed during execution.

    .PARAMETER Errors
        Array of error objects to persist. Defaults to empty array.

    .PARAMETER Version
        The vSEAL version string. Required for tracking which version performed the seal.

    .PARAMETER Path
        Optional custom path to write the status.json file. When not specified,
        defaults to C:\ProgramData\vSEAL\status.json. Use this parameter when
        writing status to an alternate location (e.g., persistent disk for Engage phase).

    .PARAMETER BaselineId
        Optional baseline ID to include in status. Only applicable for Seal phase
        when a baseline is created. Ignored for Engage phase.

    .EXAMPLE
        Write-vSEALStatus -Phase Seal -Result Success -PluginsRun 12 -PluginsFailed 0 -Version '2026.1.0'

        Writes a successful Seal status with no errors to the default location.

    .EXAMPLE
        Write-vSEALStatus -Phase Seal -Result Success -PluginsRun 12 -PluginsFailed 0 -Version '2026.1.0' -BaselineId '20260126_153045'

        Writes a successful Seal status with baseline ID for rollback reference.

    .EXAMPLE
        Write-vSEALStatus -Phase Engage -Result PartialSuccess -PluginsRun 8 -PluginsFailed 1 -Errors @($errorObj) -Version '2026.1.0'

        Writes a partial success Engage status with one error to the default location.

    .EXAMPLE
        Write-vSEALStatus -Phase Engage -Result Success -PluginsRun 8 -PluginsFailed 0 -Version '2026.1.0' -Path 'D:\vSEAL\status.json'

        Writes Engage status to a custom path on the persistent disk.

    .OUTPUTS
        [void]
    #>
    [CmdletBinding()]
    [OutputType([void])]
    param(
        [Parameter(Mandatory)]
        [ValidateSet('Seal', 'Engage', 'Rollback')]
        [string]$Phase,

        [Parameter(Mandatory)]
        [ValidateSet('Success', 'PartialSuccess', 'Failed')]
        [string]$Result,

        [Parameter(Mandatory)]
        [int]$PluginsRun,

        [Parameter(Mandatory)]
        [int]$PluginsFailed,

        [Parameter()]
        [array]$Errors = @(),

        [Parameter(Mandatory)]
        [string]$Version,

        [Parameter()]
        [string]$Path,

        [Parameter()]
        [string]$BaselineId
    )

    # Define status file path
    $statusPath = if ($Path) {
        $Path
    } else {
        Join-Path $env:ProgramData 'vSEAL\status.json'
    }
    $statusDir = Split-Path -Path $statusPath -Parent

    Write-vSEALLog "Writing $Phase status to $statusPath..." -Level VERBOSE

    # Ensure directory exists
    if (-not (Test-Path -Path $statusDir -PathType Container)) {
        $null = New-Item -Path $statusDir -ItemType Directory -Force
        Write-vSEALLog "Created status directory: $statusDir" -Level VERBOSE
    }

    # Build phase data
    $phaseData = @{
        computerName  = $env:COMPUTERNAME
        timestamp     = (Get-Date).ToUniversalTime().ToString('o')
        result        = $Result
        pluginsRun    = $PluginsRun
        pluginsFailed = $PluginsFailed
        errors        = $Errors
    }

    # Add version field only for Seal phase (per design spec)
    if ($Phase -eq 'Seal') {
        $phaseData['version'] = $Version
    }

    # Add BaselineId only for Seal phase when provided
    if ($Phase -eq 'Seal' -and $BaselineId) {
        $phaseData['baselineId'] = $BaselineId
    }

    # Load existing status or create empty structure
    $status = @{
        seal   = $null
        engage = $null
    }

    if (Test-Path -Path $statusPath -PathType Leaf) {
        try {
            $existingContent = Get-Content -Path $statusPath -Raw -ErrorAction Stop
            if (-not [string]::IsNullOrWhiteSpace($existingContent)) {
                $status = $existingContent | ConvertFrom-Json -AsHashtable -ErrorAction Stop
            }
        }
        catch {
            Write-vSEALLog "Could not read existing status file, creating new: $_" -Level WARNING
            $status = @{
                seal   = $null
                engage = $null
            }
        }
    }

    # Update status based on phase
    if ($Phase -eq 'Seal') {
        # Seal: write seal section, clear engage (new seal = fresh start)
        $status['seal'] = $phaseData
        $status['engage'] = $null
    }
    else {
        # Engage: write engage section, preserve seal section
        $status['engage'] = $phaseData
    }

    # Atomic write pattern (CRITICAL - from design spec)
    # 1. Write to temp file
    # 2. Rename to final path (atomic on NTFS)
    # 3. Flush to disk
    $tempPath = "$statusPath.tmp"

    $status | ConvertTo-Json -Depth 10 | Set-Content -Path $tempPath -Encoding utf8
    Move-Item -Path $tempPath -Destination $statusPath -Force

    # Flush to disk (prevents data loss on abrupt shutdown during VDI imaging)
    [System.IO.File]::OpenWrite($statusPath).Close()

    Write-vSEALLog "Status written: $Phase = $Result" -Level VERBOSE
}
