src/completerUtils.ps1


$sDir = "$env:LOCALAPPDATA/.ps"

function sortLastUsedFirst($vals) {
    if ($vals.getType().name -eq 'String') {
        # single element will be string, not array
        $vals = @($vals)
    }
    $valsArr = [System.Collections.ArrayList]$vals
    $lastArr = [string[]](getLastUsedNames)

    if ($lastArr) {
        $i = 0
        while ($lastArr[$i]) {
            if ($valsArr -contains $lastArr[$i]) {
                [void]($valsArr.Remove($lastArr[$i]))
                [void]($valsArr.Insert(0, $lastArr[$i]))
            }
            $i++
        }
    }
    return $valsArr
}

function removeEntredVals($commandAst, $vals) {
    # only apply to parameters like -props or -VolList
    if ($commandAst -notlike "* -*") {
        return $vals
    }
    $currValueArr = ($commandAst -replace ".+ ", '') -split ','
    $newVals = [System.Collections.ArrayList]@()
    foreach ($v in $vals) {
        if ($currValueArr -contains $v) {
            continue
        }
        [void]($newVals.Add($v))
    }
    return $newVals
}

function getCachedResourse ($path, $props, $cacheSec) {
    $cacheKey = "$path$props$cluster"
    $canTakeCache = $false
    if ($XtremCaches[$cacheKey]) {
        $saveTime = $XtremCaches[$cacheKey].time;
        $timeDiffSec = ([System.DateTime]::Now).Subtract($saveTime).TotalSeconds
        if ($timeDiffSec -le $cacheSec) {
            $canTakeCache = $true
        }
    }

    if ($canTakeCache) {
        $res = $XtremCaches[$cacheKey].value
    }
    else {
        $res = NewXtremRequest -Method GET -Endpoint $path -Session $session -XtremClusterName $cluster -GetProperty $props
        $XtremCaches[$cacheKey] = @{ }
        $XtremCaches[$cacheKey].value = $res
        $XtremCaches[$cacheKey].time = [System.DateTime]::Now
    }
    
    if ($props -like "prop=name*") {
        $res = $res.name
    }
    return $res
}

function addLastUsedPropsAndFilters($vals, $filterPart) {
    $valsArr = [System.Collections.ArrayList]$vals
    $lastArr = [string[]](getLastUsedNames)

    if ($lastArr) {
        $i = 0
        while ($lastArr[$i]) {
            if ($lastArr[$i] -match ".+:.+:.+") {
                $part1, $part2, $part3 = $lastArr[$i] -split ':'
                if ($valsArr -contains $part1 ) {

                    [void]($valsArr.Remove($lastArr[$i]))
                    $similarPattern = ($valsArr -match ("\A$part1`:$part2`:.+"))[0]
                    if ($similarPattern) {
                        [void]($valsArr.Remove($similarPattern))
                    }
                    [void]($valsArr.Insert(0, $lastArr[$i]))
                }
                elseif ($filterPart -eq 'second') {
                    # if ($valsArr -notcontains "$wtc1`:$part2") {
                    [void]($valsArr.Remove("$wtc1`:$part2"))
                    [void]($valsArr.Insert(0, "$wtc1`:$part2"))
                    # }
                }

            }
            elseif ($valsArr -contains $lastArr[$i]) {
                [void]($valsArr.Remove($lastArr[$i]))
                [void]($valsArr.Insert(0, $lastArr[$i]))
            }
            # out "$i $($lastArr[$i] -match ".+:.+:.+")" '$i'
            $i++
        }
    }
    
    return $valsArr
}

function addLastParamsFromStack($parentStack) {
    $dic = $parentStack.InvocationInfo.BoundParameters
    foreach ($kvp in $dic.getEnumerator()) {
        $values = $kvp.value
        if ($values -is [array]){
            [array]::Reverse($values)
            foreach ($val in $values) {
                addLastUsedName $val
            }
            [array]::Reverse($values)
        }else{
            addLastUsedName $values
        }
          
    }
}

function addLastUsedName($value) {
    if ($value.getType().name -eq 'String') {
        $XtremLastUsedNames = [System.Collections.ArrayList](getLastUsedNames)

        if ($value -match ".+:.+:.*") {
            # adding filter value
            $part1, $part2, $part3 = $value -split ':'
            $similarPattern = ($XtremLastUsedNames -match ("\A$part1`:$part2`:.+"))[0]
            if ($similarPattern) {
                [void]($XtremLastUsedNames.Remove($similarPattern))
            }
            $thePattern = $value
            # pass $part1 as value to add it too
            $value = $part1
        }  

        if ($XtremLastUsedNames -contains $value) {
            [void]($XtremLastUsedNames.Remove($value))
        }
        [void]$XtremLastUsedNames.Add($value)
        if ($thePattern) {
            [void]$XtremLastUsedNames.Add($thePattern)
        }


        if ($XtremLastUsedNames.Count -ge 40) {
            [void]($XtremLastUsedNames.removeAt(0))
        }
        $global:XtremLastUsedNames = $XtremLastUsedNames
        if ($XtremLastUsedNames.Count -gt 0){
            Export-Clixml -path "$sDir/last.xml" -InputObject ([string[]]($XtremLastUsedNames))
        }
    }
}

function defineSessionAndCluster {
    if ($clusterParam) {
        $cluster = $fakeBoundParameters."$clusterParam"
        if (!$cluster) {
            Write-Host "`nParameter $clusterParam must be defined. Completer in $commandName - $parameterName" -ForegroundColor Red 
        }
        $session = getSessionByClusterName $cluster
    }
    else {
        $session = (Get-XtremDefaultSession)
        $cluster = $session._XtremClusterName
    }
    return $session, $cluster
}

function getSessionByClusterName ($clusterName) {
    foreach ($sessName in $global:AllXtremSessions.Keys ) { 
        $session = $global:AllXtremSessions[$sessName]
        if ($session._XtremClusterTypeByName."$clusterName") {
            return $session
        }
    }
    return $null
}

function getAllClustersList () {
    if(!$AllXtremSessions){
        [void](Get-XtremDefaultSession)
    }
    $list = [System.Collections.ArrayList]@()
    foreach ($sessName in $AllXtremSessions.Keys ) { 
        $session = $AllXtremSessions[$sessName]
        if($session.getType().name -eq 'Hashtable'){
            foreach ($clusterName in $session._XtremClusterTypeByName.Keys ) { 
                [void]$list.Add($clusterName)
            }
        }else{
            foreach ($clusterName in $session._XtremClusterTypeByName.PSObject.Properties.Name ) { 
                [void]$list.Add($clusterName)
            }
        }
        
    }
    return $list
}

function getLastUsedNames {
    if (!$XtremLastUsedNames) {
        $global:XtremLastUsedNames = [string[]]@()
        $path = "$sDir/last.xml"
        if ([System.IO.File]::Exists($path)){
            $global:XtremLastUsedNames = [string[]](Import-Clixml -path $path)
        }
    }
    return ,$XtremLastUsedNames
}