#Requires -Version 7.4

function Get-vSEALBaselineList {
    <#
    .SYNOPSIS
        Lists all available baselines.

    .DESCRIPTION
        Returns a list of all baselines found in the baseline storage location,
        sorted by creation date (newest first). By default, only valid baselines
        are returned. Use -IncludeInvalid to include baselines that fail integrity
        checks.

    .PARAMETER Config
        Optional hashtable containing vSEAL configuration. If the configuration
        contains a baseline.path setting, that path will be used instead of the default.

    .PARAMETER IncludeInvalid
        Include baselines that fail integrity validation in the results.
        Invalid baselines will have Valid = $false.

    .EXAMPLE
        Get-vSEALBaselineList

        Returns all valid baselines sorted by creation date (newest first).

    .EXAMPLE
        Get-vSEALBaselineList -IncludeInvalid

        Returns all baselines including those with integrity issues.

    .EXAMPLE
        $config = @{ baseline = @{ path = 'D:\Baselines' } }
        Get-vSEALBaselineList -Config $config

        Returns baselines from a custom storage location.

    .OUTPUTS
        [array] Array of baseline objects with Id, Created, Status, Machine, Plugins, PluginNames, Protected, Valid, OS properties.
        The OS property contains a hashtable with Name (OS name) and BuildNumber (Windows build number).
    #>
    [CmdletBinding()]
    [OutputType([array])]
    param(
        [Parameter()]
        [hashtable]$Config,

        [Parameter()]
        [switch]$IncludeInvalid
    )

    # Resolve baseline storage path
    $basePath = Resolve-vSEALBaselinePath -Config $Config

    # Initialize results as proper array
    $results = [System.Collections.Generic.List[PSObject]]::new()

    # Return empty array if folder doesn't exist
    if (-not (Test-Path -Path $basePath -PathType Container)) {
        Write-vSEALLog "Baselines folder does not exist: $basePath" -Level VERBOSE
        return , [array]@()
    }

    # Get all folders matching timestamp pattern (YYYYMMDD_HHMMSS)
    $timestampPattern = '^\d{8}_\d{6}$'
    $folders = Get-ChildItem -Path $basePath -Directory -ErrorAction SilentlyContinue |
        Where-Object { $_.Name -match $timestampPattern } |
        Sort-Object -Property Name -Descending

    # Return empty array if no baseline folders found
    if (-not $folders -or $folders.Count -eq 0) {
        Write-vSEALLog "No baselines found in: $basePath" -Level VERBOSE
        return , [array]@()
    }

    foreach ($folder in $folders) {
        $baselinePath = $folder.FullName

        # Check integrity
        $integrity = Test-vSEALBaselineIntegrity -BaselinePath $baselinePath

        # Skip invalid baselines unless IncludeInvalid is specified
        if (-not $integrity.Valid -and -not $IncludeInvalid) {
            Write-vSEALLog "Skipping invalid baseline: $($folder.Name) - $($integrity.Reason)" -Level VERBOSE
            continue
        }

        # Build result object
        $result = @{
            Id          = $folder.Name
            Created     = $null
            Status      = $null
            Machine     = $null
            Plugins     = 0
            PluginNames = @()
            Protected   = $false
            Valid       = $integrity.Valid
            OS          = $null
        }

        # Try to read manifest for additional details
        if ($integrity.Valid) {
            $manifestPath = Join-Path $baselinePath '_manifest.json'
            try {
                $content = Get-Content -Path $manifestPath -Raw -Encoding utf8
                $manifest = $content | ConvertFrom-Json -AsHashtable

                # Map manifest fields to result
                if ($manifest.ContainsKey('created')) {
                    $result.Created = $manifest.created
                }
                if ($manifest.ContainsKey('status')) {
                    $result.Status = $manifest.status
                }
                if ($manifest.ContainsKey('machineName')) {
                    $result.Machine = $manifest.machineName
                }
                if ($manifest.ContainsKey('plugins') -and $null -ne $manifest.plugins) {
                    $result.Plugins = $manifest.plugins.Count
                    $result.PluginNames = @($manifest.plugins.Keys | Sort-Object)
                }
                if ($manifest.ContainsKey('protected')) {
                    $result.Protected = [bool]$manifest.protected
                }

                # Extract OS information (new extended format or backward compatibility)
                if ($manifest.ContainsKey('os') -and $null -ne $manifest.os) {
                    $result.OS = @{
                        Name        = $manifest.os.name
                        BuildNumber = $manifest.os.buildNumber
                    }
                } elseif ($manifest.ContainsKey('osBuild')) {
                    # Backward compatibility: old manifests only have osBuild
                    $result.OS = @{
                        Name        = $null
                        BuildNumber = $manifest.osBuild
                    }
                }
            }
            catch {
                Write-vSEALLog "Failed to read manifest for baseline: $($folder.Name)" -Level WARNING
                # Keep the baseline in results with default values
            }
        }

        $results.Add([PSCustomObject]$result)
    }

    $count = $results.Count
    Write-vSEALLog "Found $count baselines in $basePath" -Level VERBOSE

    return , [array]$results.ToArray()
}
