Eigenverft.Manifested.Drydock.Compression.ps1

function Compress-Directory {
<#
.SYNOPSIS
Creates a zip archive from a source directory in an idempotent, cross-platform way.
 
.DESCRIPTION
Uses Compress-Archive (Microsoft.PowerShell.Archive) to produce a .zip from the contents of a materialized
source directory. If the destination archive already exists, the default FilePolicy is OverwriteIfExists.
The function is idempotent: repeated runs converge without drift.
 
.PARAMETER SourceDirectory
Materialized directory whose contents will be zipped.
 
.PARAMETER DestinationFile
Full path to the resulting .zip file.
 
.PARAMETER FilePolicy
Behavior when DestinationFile already exists.
- SkipIfExists: skip work if the archive exists.
- OverwriteIfExists: replace any existing archive (default).
 
.PARAMETER CompressionLevel
Compression level for Compress-Archive.
Valid values: Optimal, Fastest, NoCompression.
 
.EXAMPLE
Compress-Directory -SourceDirectory "C:\Data\Reports" -DestinationFile "C:\Temp\reports.zip"
Creates or overwrites C:\Temp\reports.zip from directory contents (default policy).
 
.EXAMPLE
Compress-Directory -SourceDirectory "/home/carsten/projects/app" -DestinationFile "/tmp/app.zip" -FilePolicy SkipIfExists
Creates /tmp/app.zip if missing; skips if present.
 
.EXAMPLE
Compress-Directory -SourceDirectory "D:\build\out" -DestinationFile "D:\artifacts\out.zip" -CompressionLevel Fastest
Rebuilds out.zip using fastest compression.
 
.NOTES
- Compatible with Windows PowerShell 5/5.1 and PowerShell 7+ on Windows/macOS/Linux.
- No SupportsShouldProcess; no pipeline input; StrictMode-safe (v3).
- Emits minimal messages via _Write-StandardMessage for key actions only.
#>

    [CmdletBinding(PositionalBinding=$false)]
    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$SourceDirectory,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$DestinationFile,

        [Parameter()]
        [ValidateSet('SkipIfExists','OverwriteIfExists')]
        [string]$FilePolicy = 'OverwriteIfExists',

        [Parameter()]
        [ValidateSet('Optimal','Fastest','NoCompression')]
        [string]$CompressionLevel = 'Optimal'
    )

    # Inline helper for minimal, consistent console logging (scoped locally).
    function local:_Write-StandardMessage {
        [Diagnostics.CodeAnalysis.SuppressMessage("PSUseApprovedVerbs","")]
        # This function is globally exempt from the GENERAL POWERSHELL REQUIREMENTS unless explicitly stated otherwise.
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true)][AllowEmptyString()][string]$Message,
            [Parameter()][ValidateSet('TRC','DBG','INF','WRN','ERR','FTL')][string]$Level='INF',
            [Parameter()][ValidateSet('TRC','DBG','INF','WRN','ERR','FTL')][string]$MinLevel
        )

        if ($null -eq $Message) {
            $Message = [string]::Empty
        }

        $sevMap=@{TRC=0;DBG=1;INF=2;WRN=3;ERR=4;FTL=5}
        if(-not $PSBoundParameters.ContainsKey('MinLevel')){
            $gv=Get-Variable ConsoleLogMinLevel -Scope Global -ErrorAction SilentlyContinue
            $MinLevel=if($gv -and $gv.Value -and -not [string]::IsNullOrEmpty([string]$gv.Value)){[string]$gv.Value}else{'INF'}
        }
        $lvl=$Level.ToUpperInvariant()
        $min=$MinLevel.ToUpperInvariant()
        $sev=$sevMap[$lvl];if($null -eq $sev){$lvl='INF';$sev=$sevMap['INF']}
        $gate=$sevMap[$min];if($null -eq $gate){$min='INF';$gate=$sevMap['INF']}
        if($sev -ge 4 -and $sev -lt $gate -and $gate -ge 4){$lvl=$min;$sev=$gate}
        if($sev -lt $gate){return}
        $ts=[DateTime]::UtcNow.ToString('yy-MM-dd HH:mm:ss.ff')
        $stack=Get-PSCallStack ; $helperName=$MyInvocation.MyCommand.Name ; $helperScript=$MyInvocation.MyCommand.ScriptBlock.File ; $caller=$null
        if($stack){
            # 1: prefer first non-underscore function not defined in the helper's own file
            for($i=0;$i -lt $stack.Count;$i++){
                $f=$stack[$i];$fn=$f.FunctionName;$sn=$f.ScriptName
                if($fn -and $fn -ne $helperName -and -not $fn.StartsWith('_') -and (-not $helperScript -or -not $sn -or $sn -ne $helperScript)){$caller=$f;break}
            }
            # 2: fallback to first non-underscore function (any file)
            if(-not $caller){
                for($i=0;$i -lt $stack.Count;$i++){
                    $f=$stack[$i];$fn=$f.FunctionName
                    if($fn -and $fn -ne $helperName -and -not $fn.StartsWith('_')){$caller=$f;break}
                }
            }
            # 3: fallback to first non-helper frame not from helper's own file
            if(-not $caller){
                for($i=0;$i -lt $stack.Count;$i++){
                    $f=$stack[$i];$fn=$f.FunctionName;$sn=$f.ScriptName
                    if($fn -and $fn -ne $helperName -and (-not $helperScript -or -not $sn -or $sn -ne $helperScript)){$caller=$f;break}
                }
            }
            # 4: final fallback to first non-helper frame
            if(-not $caller){
                for($i=0;$i -lt $stack.Count;$i++){
                    $f=$stack[$i];$fn=$f.FunctionName
                    if($fn -and $fn -ne $helperName){$caller=$f;break}
                }
            }
        }
        if(-not $caller){$caller=[pscustomobject]@{ScriptName=$PSCommandPath;FunctionName=$null}}
        $lineNumber=$null ; 
        $p=$caller.PSObject.Properties['ScriptLineNumber'];if($p -and $p.Value){$lineNumber=[string]$p.Value}
        if(-not $lineNumber){
            $p=$caller.PSObject.Properties['Position']
            if($p -and $p.Value){
                $sp=$p.Value.PSObject.Properties['StartLineNumber'];if($sp -and $sp.Value){$lineNumber=[string]$sp.Value}
            }
        }
        if(-not $lineNumber){
            $p=$caller.PSObject.Properties['Location']
            if($p -and $p.Value){
                $m=[regex]::Match([string]$p.Value,':(\d+)\s+char:','IgnoreCase');if($m.Success -and $m.Groups.Count -gt 1){$lineNumber=$m.Groups[1].Value}
            }
        }
        $file=if($caller.ScriptName){Split-Path -Leaf $caller.ScriptName}else{'cmd'}
        if($file -ne 'console' -and $lineNumber){$file="{0}:{1}" -f $file,$lineNumber}
        $prefix="[$ts "
        $suffix="] [$file] $Message"
        $cfg=@{TRC=@{Fore='DarkGray';Back=$null};DBG=@{Fore='Cyan';Back=$null};INF=@{Fore='Green';Back=$null};WRN=@{Fore='Yellow';Back=$null};ERR=@{Fore='Red';Back=$null};FTL=@{Fore='Red';Back='DarkRed'}}[$lvl]
        $fore=$cfg.Fore
        $back=$cfg.Back
        $isInteractive = [System.Environment]::UserInteractive

        if($isInteractive -and ($fore -or $back)){
            Write-Host -NoNewline $prefix
            if($fore -and $back){Write-Host -NoNewline $lvl -ForegroundColor $fore -BackgroundColor $back}
            elseif($fore){Write-Host -NoNewline $lvl -ForegroundColor $fore}
            elseif($back){Write-Host -NoNewline $lvl -BackgroundColor $back}
            Write-Host $suffix
        } else {
            Write-Host "$prefix$lvl$suffix"
        }

        if($sev -ge 4 -and $ErrorActionPreference -eq 'Stop'){throw ("ConsoleLog.{0}: {1}" -f $lvl,$Message)}
    }

    # First call: title (no tag prefix in message)
    _Write-StandardMessage -Message '--- Compress directory to zip archive ---' -Level 'INF'

    # Require Compress-Archive (fail fast if missing).
    $compressCmd = Get-Command -Name 'Compress-Archive' -ErrorAction SilentlyContinue
    if ($null -eq $compressCmd) {
        throw 'Required cmdlet "Compress-Archive" not found. Install/enable module "Microsoft.PowerShell.Archive" or update PowerShell (5.1+/7+).'
    }

    # Resolve and validate source directory (materialized).
    $SourceResolvedPath = Resolve-Path -LiteralPath $SourceDirectory -ErrorAction SilentlyContinue
    if ($null -eq $SourceResolvedPath) {
        throw ("Source directory not found: {0}" -f $SourceDirectory)
    }
    $SourceFullPath = $SourceResolvedPath.Path
    if (-not (Test-Path -LiteralPath $SourceFullPath -PathType Container)) {
        throw ("Path is not a directory: {0}" -f $SourceFullPath)
    }

    # Ensure destination parent directory exists when needed.
    $DestinationParentPath = Split-Path -Path $DestinationFile -Parent
    if ($null -ne $DestinationParentPath -and $DestinationParentPath -ne '') {
        if (-not (Test-Path -LiteralPath $DestinationParentPath -PathType Container)) {
            New-Item -ItemType Directory -Path $DestinationParentPath -Force | Out-Null
            $DestinationParentDirectory = $DestinationParentPath
            _Write-StandardMessage -Message ("[CREATE] Created output directory: {0}" -f $DestinationParentDirectory) -Level 'INF'
        }
    }

    # Idempotency gate: handle existing archive by policy (default OverwriteIfExists).
    $DestinationFileExists = Test-Path -LiteralPath $DestinationFile -PathType Leaf
    if ($DestinationFileExists) {
        if ($FilePolicy -eq 'SkipIfExists') {
            _Write-StandardMessage -Message ("[SKIP] Zip already present, skipped: {0}" -f $DestinationFile) -Level 'INF'
            return
        }
        if ($FilePolicy -eq 'OverwriteIfExists') {
            Remove-Item -LiteralPath $DestinationFile -Force
            _Write-StandardMessage -Message ("[OVERWRITE] Removed existing zip (overwrite policy): {0}" -f $DestinationFile) -Level 'INF'
        }
    }

    # Compress directory contents (not the root directory node).
    $SourceContentPattern = Join-Path -Path $SourceFullPath -ChildPath '*'

    $oldProgressPreference = $ProgressPreference
    try {
        # Temporarily suppress progress bar from Compress-Archive.
        $ProgressPreference = 'SilentlyContinue'

        _Write-StandardMessage -Message (
            "[STATUS] Starting compression from '{0}' to '{1}' (Level={2}, Policy={3})." -f
            $SourceFullPath, $DestinationFile, $CompressionLevel, $FilePolicy
        ) -Level 'INF'

        Compress-Archive -Path $SourceContentPattern -DestinationPath $DestinationFile -CompressionLevel $CompressionLevel
    } catch {
        $ErrorMessage = $_.Exception.Message
        _Write-StandardMessage -Message ("[ERR] Failed to create archive: {0}" -f $ErrorMessage) -Level 'ERR'
        throw ("Failed to create archive. {0}" -f $ErrorMessage)
    } finally {
        # Restore previous progress preference.
        $ProgressPreference = $oldProgressPreference
    }

    _Write-StandardMessage -Message ("[OK] Compression finished, created zip: {0}" -f $DestinationFile) -Level 'INF'
}

function Add-FileToZipArchive {
<#
.SYNOPSIS
    Adds or updates a single file in a zip archive.
 
.DESCRIPTION
    Uses System.IO.Compression.ZipArchive to add or update a single file inside a .zip archive.
    If the destination zip does not exist, it is created.
    Optionally deletes the source file after a successful update.
    Entry behavior when an item already exists inside the zip is controlled via EntryPolicy.
    Optionally places the file into a date-based subfolder inside the zip based on UTC time.
    Includes a retry policy and a failure policy (Strict vs BestEffort).
 
.PARAMETER SourceFile
    Full path to the file that should be stored inside the zip.
 
.PARAMETER DestinationZip
    Full path to the target .zip archive. Created if it does not exist.
 
.PARAMETER CompressionLevel
    Compression level for the zip entry.
    Valid values: Optimal, Fastest, NoCompression.
 
.PARAMETER EntryPolicy
    Behavior when an entry with the same name already exists in the zip.
    - OverwriteIfExists (default): overwrite the existing entry.
    - SkipIfExists: skip this file if an entry already exists.
    - FailIfExists: throw (or skip in BestEffort mode) if an entry already exists.
 
.PARAMETER DeleteSource
    Controls whether the source file is deleted after a successful write to the zip.
    - Delete (default): delete the source file.
    - Keep: keep the source file.
 
.PARAMETER DateFolderPattern
    Controls whether the entry is placed into a UTC date-based subfolder inside the zip.
    - None (default): no date subfolder, just the filename.
    - YYMMDD: folder like archived-at_utc_241123.
    - YYYYMMDD: folder like archived-at_utc_20251123.
    - YYYYMM: folder like archived-at_utc_202511.
    - YYYY: folder like archived-at_utc_2025.
    - YYYYMMDD_HH: folder like archived-at_utc_20251123_09 (hourly buckets).
 
.PARAMETER RetryCount
    Number of attempts to write into the zip before failing or skipping.
    Default: 3.
 
.PARAMETER RetryDelayMilliseconds
    Delay between retry attempts, in milliseconds.
    Default: 500.
 
.PARAMETER FailurePolicy
    Controls how failures are surfaced.
    - Strict (default): throw on unrecoverable failures.
    - BestEffort: log and skip on unrecoverable failures (no throw).
 
.EXAMPLE
    Add-FileToZipArchive -SourceFile "C:\Logs\app-2025-11-23.log" -DestinationZip "C:\Archives\logs.zip"
 
.EXAMPLE
    Add-FileToZipArchive -SourceFile "/var/log/app.log.1" -DestinationZip "/var/archive/app-logs.zip" -DeleteSource Keep
 
.EXAMPLE
    Add-FileToZipArchive -SourceFile "/var/log/app.log.1" -DestinationZip "/var/archive/app-logs.zip" -EntryPolicy SkipIfExists
 
.EXAMPLE
    # Store entries in daily UTC subfolders, e.g. archived-at_utc_241123/app.log
    Add-FileToZipArchive -SourceFile "C:\Logs\app.log" -DestinationZip "C:\Archives\logs.zip" -DateFolderPattern YYMMDD
 
.EXAMPLE
    # Best-effort behavior for scheduled tasks: never throw on zip contention
    Add-FileToZipArchive -SourceFile "C:\Logs\app.log" -DestinationZip "C:\Archives\logs.zip" -FailurePolicy BestEffort
#>

    [CmdletBinding(PositionalBinding=$false)]
    [Alias("Into-Zip")]
    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$SourceFile,

        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$DestinationZip,

        [Parameter()]
        [ValidateSet('Optimal','Fastest','NoCompression')]
        [string]$CompressionLevel = 'Optimal',

        [Parameter()]
        [ValidateSet('OverwriteIfExists','SkipIfExists','FailIfExists')]
        [string]$EntryPolicy = 'OverwriteIfExists',

        [Parameter()]
        [ValidateSet('Delete','Keep')]
        [string]$DeleteSource = 'Delete',

        [Parameter()]
        [ValidateSet('None','YYMMDD','YYYYMMDD','YYYYMM','YYYY','YYYYMMDD_HH')]
        [string]$DateFolderPattern = 'None',

        [Parameter()]
        [ValidateRange(1,60)]
        [int]$RetryCount = 3,

        [Parameter()]
        [ValidateRange(10,600000)]
        [int]$RetryDelayMilliseconds = 500,

        [Parameter()]
        [ValidateSet('Strict','BestEffort')]
        [string]$FailurePolicy = 'BestEffort'
    )

    function local:_Write-StandardMessage {
        [Diagnostics.CodeAnalysis.SuppressMessage("PSUseApprovedVerbs","")]
        [CmdletBinding()]
        param(
            [Parameter(Mandatory=$true)][AllowEmptyString()][string]$Message,
            [Parameter()][ValidateSet('TRC','DBG','INF','WRN','ERR','FTL')][string]$Level='INF',
            [Parameter()][ValidateSet('TRC','DBG','INF','WRN','ERR','FTL')][string]$MinLevel
        )

        if ($null -eq $Message) {
            $Message = [string]::Empty
        }

        $sevMap=@{TRC=0;DBG=1;INF=2;WRN=3;ERR=4;FTL=5}
        if(-not $PSBoundParameters.ContainsKey('MinLevel')){
            $gv=Get-Variable ConsoleLogMinLevel -Scope Global -ErrorAction SilentlyContinue
            $MinLevel=if($gv -and $gv.Value -and -not [string]::IsNullOrEmpty([string]$gv.Value)){[string]$gv.Value}else{'INF'}
        }
        $lvl=$Level.ToUpperInvariant()
        $min=$MinLevel.ToUpperInvariant()
        $sev=$sevMap[$lvl];if($null -eq $sev){$lvl='INF';$sev=$sevMap['INF']}
        $gate=$sevMap[$min];if($null -eq $gate){$min='INF';$gate=$sevMap['INF']}
        if($sev -ge 4 -and $sev -lt $gate -and $gate -ge 4){$lvl=$min;$sev=$gate}
        if($sev -lt $gate){return}
        $ts=[DateTime]::UtcNow.ToString('yy-MM-dd HH:mm:ss.ff')
        $stack=Get-PSCallStack ; $helperName=$MyInvocation.MyCommand.Name ; $helperScript=$MyInvocation.MyCommand.ScriptBlock.File ; $caller=$null
        if($stack){
            for($i=0;$i -lt $stack.Count;$i++){
                $f=$stack[$i];$fn=$f.FunctionName;$sn=$f.ScriptName
                if($fn -and $fn -ne $helperName -and -not $fn.StartsWith('_') -and (-not $helperScript -or -not $sn -or $sn -ne $helperScript)){$caller=$f;break}
            }
            if(-not $caller){
                for($i=0;$i -lt $stack.Count;$i++){
                    $f=$stack[$i];$fn=$f.FunctionName
                    if($fn -and $fn -ne $helperName -and -not $fn.StartsWith('_')){$caller=$f;break}
                }
            }
            if(-not $caller){
                for($i=0;$i -lt $stack.Count;$i++){
                    $f=$stack[$i];$fn=$f.FunctionName;$sn=$f.ScriptName
                    if($fn -and $fn -ne $helperName -and (-not $helperScript -or -not $sn -or $sn -ne $helperScript)){$caller=$f;break}
                }
            }
            if(-not $caller){
                for($i=0;$i -lt $stack.Count;$i++){
                    $f=$stack[$i];$fn=$f.FunctionName
                    if($fn -and $fn -ne $helperName){$caller=$f;break}
                }
            }
        }
        if(-not $caller){$caller=[pscustomobject]@{ScriptName=$PSCommandPath;FunctionName=$null}}
        $lineNumber=$null
        $p=$caller.PSObject.Properties['ScriptLineNumber'];if($p -and $p.Value){$lineNumber=[string]$p.Value}
        if(-not $lineNumber){
            $p=$caller.PSObject.Properties['Position']
            if($p -and $p.Value){
                $sp=$p.Value.PSObject.Properties['StartLineNumber'];if($sp -and $sp.Value){$lineNumber=[string]$sp.Value}
            }
        }
        if(-not $lineNumber){
            $p=$caller.PSObject.Properties['Location']
            if($p -and $p.Value){
                $m=[regex]::Match([string]$p.Value,':(\d+)\s+char:','IgnoreCase');if($m.Success -and $m.Groups.Count -gt 1){$lineNumber=$m.Groups[1].Value}
            }
        }
        $file=if($caller.ScriptName){Split-Path -Leaf $caller.ScriptName}else{'cmd'}
        if($file -ne 'console' -and $lineNumber){$file="{0}:{1}" -f $file,$lineNumber}
        $prefix="[$ts "
        $suffix="] [$file] $Message"
        $cfg=@{
            TRC=@{Fore='DarkGray';Back=$null}
            DBG=@{Fore='Cyan';Back=$null}
            INF=@{Fore='Green';Back=$null}
            WRN=@{Fore='Yellow';Back=$null}
            ERR=@{Fore='Red';Back=$null}
            FTL=@{Fore='Red';Back='DarkRed'}
        }[$lvl]
        $fore=$cfg.Fore
        $back=$cfg.Back
        $isInteractive = [System.Environment]::UserInteractive

        if($isInteractive -and ($fore -or $back)){
            Write-Host -NoNewline $prefix
            if($fore -and $back){Write-Host -NoNewline $lvl -ForegroundColor $fore -BackgroundColor $back}
            elseif($fore){Write-Host -NoNewline $lvl -ForegroundColor $fore}
            elseif($back){Write-Host -NoNewline $lvl -BackgroundColor $back}
            Write-Host $suffix
        } else {
            Write-Host "$prefix$lvl$suffix"
        }

        if($sev -ge 4 -and $ErrorActionPreference -eq 'Stop'){throw ("ConsoleLog.{0}: {1}" -f $lvl,$Message)}
    }

    # First call: title (no tag prefix in message)
    _Write-StandardMessage -Message '--- Add single file into zip archive ---' -Level 'INF'

    # Resolve and validate source file, but SKIP/WARN if missing or invalid.
    $SourceResolved = Resolve-Path -LiteralPath $SourceFile -ErrorAction SilentlyContinue
    if ($null -eq $SourceResolved) {
        _Write-StandardMessage -Message ("[SKIP] Source file not found; skipping: {0}" -f $SourceFile) -Level 'WRN'
        return
    }
    $SourceFullPath = $SourceResolved.Path
    if (-not (Test-Path -LiteralPath $SourceFullPath -PathType Leaf)) {
        _Write-StandardMessage -Message ("[SKIP] Path is not a file; skipping: {0}" -f $SourceFullPath) -Level 'WRN'
        return
    }

    # Build date-based subfolder (UTC) if requested, using "archived-at_utc_<pattern>".
    $utcNow     = [DateTime]::UtcNow
    $dateCore   = $null
    switch ($DateFolderPattern) {
        'None'        { $dateCore = $null }
        'YYMMDD'      { $dateCore = $utcNow.ToString('yyMMdd') }
        'YYYYMMDD'    { $dateCore = $utcNow.ToString('yyyyMMdd') }
        'YYYYMM'      { $dateCore = $utcNow.ToString('yyyyMM') }
        'YYYY'        { $dateCore = $utcNow.ToString('yyyy') }
        'YYYYMMDD_HH' { $dateCore = $utcNow.ToString('yyyyMMdd_HH') }
        default       { $dateCore = $null }
    }

    $dateFolder = if ([string]::IsNullOrEmpty($dateCore)) {
        $null
    } else {
        "archived-at_utc_{0}" -f $dateCore
    }

    # Ensure destination parent directory exists when needed.
    $DestinationParentPath = Split-Path -Path $DestinationZip -Parent
    if ($null -ne $DestinationParentPath -and $DestinationParentPath -ne '') {
        if (-not (Test-Path -LiteralPath $DestinationParentPath -PathType Container)) {
            New-Item -ItemType Directory -Path $DestinationParentPath -Force | Out-Null
            _Write-StandardMessage -Message ("[CREATE] Created output directory: {0}" -f $DestinationParentPath) -Level 'INF'
        }
    }

    $zipExists       = Test-Path -LiteralPath $DestinationZip -PathType Leaf
    $entryLeafName   = [System.IO.Path]::GetFileName($SourceFullPath)
    $entryName       = if ([string]::IsNullOrEmpty($dateFolder)) {
                           $entryLeafName
                       } else {
                           "{0}/{1}" -f $dateFolder, $entryLeafName
                       }

    $operationResult = 'None' # 'None' | 'Wrote' | 'Skipped'

    for ($attempt = 1; $attempt -le $RetryCount; $attempt++) {
        $fs  = $null
        $zip = $null

        try {
            $fsMode  = if ($zipExists) { [System.IO.FileMode]::Open } else { [System.IO.FileMode]::Create }
            $zipMode = if ($zipExists) { [System.IO.Compression.ZipArchiveMode]::Update } else { [System.IO.Compression.ZipArchiveMode]::Create }

            if (-not $zipExists -and $attempt -eq 1) {
                _Write-StandardMessage -Message ("[CREATE] Creating new zip archive: {0}" -f $DestinationZip) -Level 'INF'
            } elseif ($zipExists -and $attempt -eq 1) {
                _Write-StandardMessage -Message ("[STATUS] Opening existing zip archive: {0}" -f $DestinationZip) -Level 'INF'
            }

            $fs  = [System.IO.File]::Open($DestinationZip, $fsMode, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
            $zip = New-Object System.IO.Compression.ZipArchive($fs, $zipMode, $false)

            # Inspect existing entries (match by full entry name, including optional date folder).
            $existingEntry = $null
            foreach ($e in $zip.Entries) {
                if ($e.FullName -eq $entryName) {
                    $existingEntry = $e
                    break
                }
            }

            if ($existingEntry) {
                switch ($EntryPolicy) {
                    'SkipIfExists' {
                        _Write-StandardMessage -Message ("[SKIP] Entry '{0}' already exists in '{1}'; skipping and keeping source file: {2}" -f $entryName, $DestinationZip, $SourceFullPath) -Level 'INF'
                        $operationResult = 'Skipped'
                        return
                    }
                    'FailIfExists' {
                        if ($FailurePolicy -eq 'BestEffort') {
                            _Write-StandardMessage -Message (
                                "[SKIP] (BestEffort) Entry '{0}' already exists in '{1}' (EntryPolicy=FailIfExists, FailurePolicy=BestEffort); treating as warning and skipping, keeping source file: {2}" -f
                                $entryName, $DestinationZip, $SourceFullPath
                            ) -Level 'WRN'
                            $operationResult = 'Skipped'
                            return
                        } else {
                            _Write-StandardMessage -Message (
                                "[ERR] Entry '{0}' already exists in '{1}' (EntryPolicy=FailIfExists)." -f
                                $entryName, $DestinationZip
                            ) -Level 'ERR'
                            throw ("Zip entry '{0}' already exists in '{1}' and EntryPolicy is FailIfExists." -f $entryName, $DestinationZip)
                        }
                    }
                    'OverwriteIfExists' {
                        _Write-StandardMessage -Message ("[STATUS] Entry '{0}' already exists in '{1}'; overwriting per EntryPolicy." -f $entryName, $DestinationZip) -Level 'INF'
                        $existingEntry.Delete()
                    }
                }
            } else {
                if ($zipExists) {
                    _Write-StandardMessage -Message ("[STATUS] Adding new entry '{0}' to existing archive: {1}" -f $entryName, $DestinationZip) -Level 'INF'
                }
            }

            _Write-StandardMessage -Message (
                "[STATUS] Writing file '{0}' as entry '{1}' to '{2}' (Level={3}, EntryPolicy={4}, Attempt={5}/{6})." -f
                $SourceFullPath, $entryName, $DestinationZip, $CompressionLevel, $EntryPolicy, $attempt, $RetryCount
            ) -Level 'INF'

            $compressionEnum = [System.IO.Compression.CompressionLevel]::$CompressionLevel
            $entry           = $zip.CreateEntry($entryName, $compressionEnum)

            $sourceStream = $null
            $entryStream  = $null
            try {
                $sourceStream = [System.IO.File]::OpenRead($SourceFullPath)
                $entryStream  = $entry.Open()
                $sourceStream.CopyTo($entryStream)
            } finally {
                if ($entryStream)  { $entryStream.Dispose() }
                if ($sourceStream) { $sourceStream.Dispose() }
            }

            _Write-StandardMessage -Message ("[OK] File stored in zip as '{0}' in '{1}'." -f $entryName, $DestinationZip) -Level 'INF'
            $operationResult = 'Wrote'
            break
        } catch {
            $err = $_.Exception.Message
            if ($attempt -lt $RetryCount) {
                _Write-StandardMessage -Message (
                    "[RETRY] Failed to add file to zip (attempt {0}/{1}); retrying in {2} ms. Error: {3}" -f
                    $attempt, $RetryCount, $RetryDelayMilliseconds, $err
                ) -Level 'WRN'
                Start-Sleep -Milliseconds $RetryDelayMilliseconds
                continue
            } else {
                if ($FailurePolicy -eq 'BestEffort') {
                    _Write-StandardMessage -Message (
                        "[SKIP] (BestEffort) Failed to add file to zip after {0} attempts; treating as warning and giving up, continuing run. Error: {1}" -f
                        $RetryCount, $err
                    ) -Level 'WRN'
                    $operationResult = 'Skipped'
                    return
                } else {
                    _Write-StandardMessage -Message (
                        "[ERR] Failed to add file to zip after {0} attempts: {1}" -f
                        $RetryCount, $err
                    ) -Level 'ERR'
                    throw ("Failed to add file to zip after {0} attempts. {1}" -f $RetryCount, $err)
                }
            }
        } finally {
            if ($zip) { $zip.Dispose() }
            if ($fs)  { $fs.Dispose()  }
        }
    }

    if ($operationResult -eq 'Wrote' -and $DeleteSource -eq 'Delete') {
        try {
            Remove-Item -LiteralPath $SourceFullPath -Force
            _Write-StandardMessage -Message ("[DELETE] Removed source file: {0}" -f $SourceFullPath) -Level 'INF'
        } catch {
            $err2 = $_.Exception.Message
            if ($FailurePolicy -eq 'BestEffort') {
                _Write-StandardMessage -Message (
                    "[WRN] (BestEffort) Failed to delete source file '{0}'; treating as warning and continuing. Error: {1}" -f
                    $SourceFullPath, $err2
                ) -Level 'WRN'
                return
            } else {
                _Write-StandardMessage -Message (
                    "[WRN] Failed to delete source file '{0}': {1}" -f
                    $SourceFullPath, $err2
                ) -Level 'WRN'
                throw ("Failed to delete source file '{0}': {1}" -f $SourceFullPath, $err2)
            }
        }
    }
}

# Add-FileToZipArchive -SourceFile "C:\Temp\Eigenverft.App.ReverseProxy-drops\sln\Eigenverft.App.ReverseProxy\production\0.1.20256.47288\LICENSE-SERILOG_EXTENSIONS_HOSTING" -DestinationZip "C:\Archives\logs.zip" -DateFolderPattern YYYYMMDD
# Write-Output "Done"