scripts/modules/shared/loop-functions.ps1

# strangeloop Setup - Shared Loop Functions
# Version: 1.0.0


# Loop management and platform detection functions

function Get-KnownLoops {
    <#
    .SYNOPSIS
        Returns the registry of all known strangeloop loops with their platform requirements
    
    .DESCRIPTION
        Central registry of all available loops and their platform requirements.
        This is the single source of truth for loop definitions.
    #>

    
    return @{
        # WSL-based loops
        'python-mcp-server' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Model Context Protocol server in Python' }
        'python-cli' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Command-line application in Python' }
        'python-semantic-kernel-agent' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Semantic Kernel agent in Python' }
        'flask-linux' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Flask web application for Linux' }
        'langgraph-agent' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'LangGraph agent application' }
        'csharp-mcp-server' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Model Context Protocol server in C#' }
        'csharp-semantic-kernel-agent' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = 'Semantic Kernel agent in C#' }
        'csharp-dotnet-aspire' = @{ Platform = 'WSL'; RequiresWSL = $true; RequiresWindows = $false; Description = '.NET Aspire cloud application' }
        
        # Windows-based loops
        'asp-dotnet-framework-api' = @{ Platform = 'Windows'; RequiresWSL = $false; RequiresWindows = $true; Description = 'ASP.NET Framework API' }
        'ads-snr-basic' = @{ Platform = 'Windows'; RequiresWSL = $false; RequiresWindows = $true; Description = 'Ads SNR basic service' }
        'flask-windows' = @{ Platform = 'Windows'; RequiresWSL = $false; RequiresWindows = $true; Description = 'Flask web application for Windows' }
    }
}

function Test-LoopExists {
    <#
    .SYNOPSIS
        Tests if a loop name exists in the known loops registry
    
    .PARAMETER LoopName
        The name of the loop to validate
    #>

    param(
        [Parameter(Mandatory)]
        [string]$LoopName
    )
    
    $knownLoops = Get-KnownLoops
    return $knownLoops.ContainsKey($LoopName)
}

function Get-LoopRequirements {
    <#
    .SYNOPSIS
        Gets platform requirements for a specific loop
    
    .PARAMETER LoopName
        The name of the loop to get requirements for
    
    .RETURNS
        Hashtable with Platform, RequiresWSL, RequiresWindows properties, or $null if loop not found
    #>

    param(
        [Parameter(Mandatory)]
        [string]$LoopName
    )
    
    $knownLoops = Get-KnownLoops
    if ($knownLoops.ContainsKey($LoopName)) {
        return $knownLoops[$LoopName]
    }
    
    return $null
}

function Test-LoopAndGetRequirements {
    <#
    .SYNOPSIS
        Validates a loop name and returns discovery-like results
    
    .PARAMETER LoopName
        The name of the loop to validate
    
    .RETURNS
        Hashtable with discovery results if valid, $null if invalid
    #>

    param(
        [Parameter(Mandatory)]
        [string]$LoopName
    )
    
    $knownLoops = Get-KnownLoops
    
    if ($knownLoops.ContainsKey($LoopName)) {
        $requirements = $knownLoops[$LoopName]
        
        Write-Host "✓ Pre-validated loop: $LoopName" -ForegroundColor Green
        Write-Host "✓ Target platform: $($requirements.Platform)" -ForegroundColor Green
        
        return @{
            Success = $true
            SelectedLoop = $LoopName
            EnvironmentRequirements = @{
                RequiresWSL = $requirements.RequiresWSL
                RequiresWindows = $requirements.RequiresWindows
                SelectedLoop = $LoopName
                Platform = $requirements.Platform
            }
            AvailableLoops = @($knownLoops.Keys)
            SkippedDiscovery = $true
        }
    } else {
        Write-Error "Loop '$LoopName' not found in the known loops registry."
        Write-Host ""
        Write-Host "Available loops:" -ForegroundColor Yellow
        $knownLoops.Keys | Sort-Object | ForEach-Object { 
            $loop = $knownLoops[$_]
            Write-Host " • $_ (Platform: $($loop.Platform)) - $($loop.Description)" -ForegroundColor Gray
        }
        Write-Host ""
        Write-Host "Usage:" -ForegroundColor Yellow
        Write-Host " .\setup-strangeloop.ps1 -loop-name 'csharp-mcp-server' # Use correct loop name" -ForegroundColor Gray
        Write-Host " .\setup-strangeloop.ps1 # Interactive selection" -ForegroundColor Gray
        Write-Host " .\setup-strangeloop.ps1 -help # Show all options" -ForegroundColor Gray
        Write-Host ""
        return $null
    }
}

function Get-LoopsByPlatform {
    <#
    .SYNOPSIS
        Gets loops grouped by platform
    
    .PARAMETER Platform
        Optional platform filter ('Windows' or 'WSL')
    
    .RETURNS
        Array of loop names for the specified platform, or hashtable grouped by platform
    #>

    param(
        [ValidateSet('Windows', 'WSL')]
        [string]$Platform
    )
    
    $knownLoops = Get-KnownLoops
    
    if ($Platform) {
        return $knownLoops.Keys | Where-Object { $knownLoops[$_].Platform -eq $Platform }
    } else {
        $platforms = @{
            'Windows' = @()
            'WSL' = @()
        }
        
        foreach ($loopName in $knownLoops.Keys) {
            $loop = $knownLoops[$loopName]
            $platforms[$loop.Platform] += $loopName
        }
        
        return $platforms
    }
}

function Test-PathPlatformCompatibility {
    <#
    .SYNOPSIS
        Tests if a project path is compatible with a loop's platform requirements
    
    .PARAMETER ProjectPath
        The project path to validate
    
    .PARAMETER LoopName
        The loop name to check compatibility for
    
    .RETURNS
        Hashtable with IsCompatible, SuggestedPath, and Platform properties
    #>

    param(
        [Parameter(Mandatory)]
        [string]$ProjectPath,
        
        [Parameter(Mandatory)]
        [string]$LoopName
    )
    
    $requirements = Get-LoopRequirements -LoopName $LoopName
    if (-not $requirements) {
        throw "Unknown loop: $LoopName"
    }
    
    $isWindowsPath = $ProjectPath -match '^[A-Za-z]:\\'
    $isWSLPath = $ProjectPath.StartsWith('/') -or $ProjectPath.Contains('/home/')
    $requiresWSL = $requirements.RequiresWSL
    
    $result = @{
        IsCompatible = $true
        SuggestedPath = $ProjectPath
        Platform = $requirements.Platform
        RequiresWSL = $requiresWSL
    }
    
    if ($requiresWSL -and $isWindowsPath) {
        # WSL loop with Windows path - suggest WSL path
        $projectName = Split-Path $ProjectPath -Leaf
        $result.IsCompatible = $false
        try {
            $wslUser = & wsl -- whoami 2>$null
            if ($wslUser) {
                $result.SuggestedPath = "/home/$($wslUser.Trim())/AdsSnR_Containers/services/$projectName"
            } else {
                $result.SuggestedPath = "/home/\$USER/AdsSnR_Containers/services/$projectName"
            }
        } catch {
            $result.SuggestedPath = "/home/\$USER/AdsSnR_Containers/services/$projectName"
        }
    } elseif (-not $requiresWSL -and $isWSLPath) {
        # Windows loop with WSL path - suggest Windows path
        $projectName = Split-Path $ProjectPath -Leaf
        $result.IsCompatible = $false
        $result.SuggestedPath = "Q:\src\AdsSnR_Containers\services\$projectName"
    }
    
    return $result
}