functions/Import-CmdFav.ps1

function Import-CmdFav {
    <#
    .SYNOPSIS
        Imports favorite commands from a file and adds them to the cache.
 
    .DESCRIPTION
        The Import-CmdFav function imports favorite commands from a file (JSON, XML, or PSM) and adds them to the cache.
        If the specified file does not exist or contains invalid data, an error message is displayed.
 
    .PARAMETER Path
        Specifies the path to the file containing favorite commands. This parameter is mandatory.
 
    .PARAMETER Format
        Specifies the format of the import file. Valid values: JSON, XML, PSM. Default: JSON.
 
    .EXAMPLE
        Import-CmdFav -Path "C:\Path\To\Favorites.json" -Format JSON
 
        Imports favorite commands from the specified JSON file and adds them to the cache.
    #>

    [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')]
    param (
        [parameter(mandatory = $true, Position = 1)]
        [String]$Path,
        [ValidateSet('AUTO', 'JSON', 'XML', 'PSM')]
        [string]$Format = 'AUTO',
        [ValidateSet('REPLACE', 'APPEND', 'OVERWRITE')]
        [string]$ImportMode = 'REPLACE',
        [string[]]$Name
    )

    $Path = (Resolve-Path $Path).ProviderPath
    Write-PSFMessage -Level Verbose -Message "Importing CmdFav favorites from file: $Path (Format: $Format)"
    if (-not (Test-Path -Path $Path -PathType Leaf)) {
        Stop-PSFFunction -Level Error -Message "File not found: $Path"
        return
    }

    $actualFormat = $Format
    if ($Format -eq 'AUTO') {
        switch -Regex ($Path) {
            '\.json$' { $actualFormat = 'JSON' }
            '\.xml$' { $actualFormat = 'XML' }
            '\.psm1$' { $actualFormat = 'PSM' }
            default {
                Stop-PSFFunction -Level Error -Message "Could not determine file format by file extension in: $Path. Use -Format [JSON|XML|PSM] instead AUTO."
                return
            }
        }
    }

    try {
        switch ($actualFormat) {
            'JSON' {
                $importedCmds = Get-Content -Path $Path | ConvertFrom-Json
            }
            'XML' {
                $importedCmds = Import-PSFClixml -Path $Path -Encoding UTF8
            }
            'PSM' {
                $ast = [System.Management.Automation.Language.Parser]::ParseFile($Path, [ref]$null, [ref]$null)

                # Alle Funktionsdefinitionen extrahieren
                $functions = $ast.FindAll({ $args[0] -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true)

                $importedCmds = @()
                foreach ($func in $functions) {
                     $helpContent=$func.GetHelpContent()
                    $desc = $helpContent.description

                    $tags = @()
                    $repo = 'PERSONALDEFAULT'
                    if ($helpContent.Notes) {
                        if ($helpContent.Notes -match 'Tags:\s*(.+)') {
                            $tags = $matches[1] -split ',' | ForEach-Object { $_.Trim() }
                        }
                        if ($helpContent.Notes -match 'Repository:\s*(.+)') {
                            $repo = $matches[1].Trim()
                        }
                    }
                    $cmd = @{
                        Name        = $func.Name
                        CommandLine = ($func.Body.EndBlock.ToString()).Trim()  | Format-CmdFavString
                        Description = $desc
                        Tag         = $tags
                        Repository  = $repo
                    }
                    # $cmd|json
                    $importedCmds += [PSCustomObject]$cmd
                }
            }
        }
    }
    catch {
        Stop-PSFFunction -Level Error -Message "Failed to import favorite commands from $Path. Invalid $actualFormat format."
        return
    }
    Write-PSFMessage -Level Verbose -Message "Imported RAW commands: $($importedCmds.Name -join ', ')"
    if ($Name) {
        $importedCmds = $importedCmds | Where-Object { $Name -contains $_.Name }
    }
    $oldCache = Get-CmdFavCache
    $confirmMessage = ''
    $newCmdCache = $null
    $oldCount = $oldCache.Count
    $importCount = $importedCmds.Count
    switch ($ImportMode) {
        'REPLACE' {
            $confirmMessage = "Replace all existing $oldCount favorites with $importCount from $Path"
            $newCmdCache = $importedCmds
        }
        'APPEND' {
            $newEntries = $importedCmds | Where-Object { -not ($oldCache.Name -contains $_.Name) }
            $confirmMessage = "Append $($newEntries.count) imported favorites to existing $oldCount in cache, if they do not exist"
            $newCmdCache = $oldCache + $newEntries
        }
        'OVERWRITE' {
            $newEntries = [array]($importedCmds | Where-Object { -not ($oldCache.Name -contains $_.Name) })
            $overWriteEntries = [array]($importedCmds | Where-Object { $oldCache.Name -contains $_.Name })
            $keepEntries = [array]($oldCache | Where-Object { $importedCmds.Name -notcontains $_.Name })

            $confirmMessage = "Overwrite $($overWriteEntries.count) existing favorites, adding $($newEntries.count) new and keeping $($keepEntries.count)"
            $newCmdCache = $newEntries + $overWriteEntries + $keepEntries
        }
    }
    Write-PSFMessage -Level Verbose -Message "`$newCmdCache= $($newCmdCache.Name -join ', ')"
    Invoke-PSFProtectedCommand -ScriptBlock {
        Set-CmdFavCache -CmdCache $newCmdCache
        Save-CmdFav
    } -Action $confirmMessage
}