MetaNull.LaravelUtils.psm1

# Module Constants and Initialization

# Icon configuration based on PowerShell version
$script:ModuleIcons = @{}
$script:UseEmojis = $false

# Detect PowerShell version and set icon preference
if ($PSVersionTable.PSVersion.Major -ge 7) {
    # PowerShell 7+ supports Unicode emojis better
    $script:UseEmojis = $true
    $script:ModuleIcons = @{
        # Status Icons
        Rocket = "🚀"
        CheckMark = "✅"
        Warning = "⚠️"
        Info = "ℹ️"
        Error = "❌"

        # Application Icons
        Celebration = "🎉"
        MobilePhone = "📱"
        Satellite = "📡"
        Lightning = "⚡"

        # Tool Icons
        Wrench = "🔧"
        Books = "📚"
        GreenHeart = "💚"
        Key = "🔑"
        FloppyDisk = "💾"

        # Fallback plain text versions
        PlainText = @{
            Rocket = "[START]"
            CheckMark = "[OK]"
            Warning = "[WARN]"
            Info = "[INFO]"
            Error = "[ERROR]"
            Celebration = "[SUCCESS]"
            MobilePhone = "[APP]"
            Satellite = "[API]"
            Lightning = "[HMR]"
            Wrench = "[TOOLS]"
            Books = "[DOCS]"
            GreenHeart = "[HEALTH]"
            Key = "[DASH]"
            FloppyDisk = "[DEV]"
        }
    }
} else {
    # PowerShell 5.1 and earlier - use plain text icons
    $script:UseEmojis = $false
    $script:ModuleIcons = @{
        PlainText = @{
            Rocket = "[START]"
            CheckMark = "[OK]"
            Warning = "[WARN]"
            Info = "[INFO]"
            Error = "[ERROR]"
            Celebration = "[SUCCESS]"
            MobilePhone = "[APP]"
            Satellite = "[API]"
            Lightning = "[HMR]"
            Wrench = "[TOOLS]"
            Books = "[DOCS]"
            GreenHeart = "[HEALTH]"
            Key = "[DASH]"
            FloppyDisk = "[DEV]"
        }
    }
}

# Color constants for consistent output
Set-Variable -Name "ModuleColorSuccess" -Value "Green" -Option Constant
Set-Variable -Name "ModuleColorWarning" -Value "Yellow" -Option Constant
Set-Variable -Name "ModuleColorError" -Value "Red" -Option Constant
Set-Variable -Name "ModuleColorInfo" -Value "Cyan" -Option Constant
Set-Variable -Name "ModuleColorStep" -Value "Magenta" -Option Constant
Function Get-DevIcon {
<#
    .SYNOPSIS
    Gets an icon for display based on PowerShell version capabilities
 
    .DESCRIPTION
    Returns either an emoji icon (PowerShell 7+) or plain text fallback (PowerShell 5.1).
    This is a public wrapper around the private Get-ModuleIcon function.
 
    .PARAMETER IconName
    The name of the icon to retrieve. Valid values include:
    Rocket, CheckMark, Warning, Info, Error, Celebration, MobilePhone,
    Satellite, Lightning, Wrench, Books, GreenHeart, Key, FloppyDisk
 
    .OUTPUTS
    String - The icon character or text representation
 
    .EXAMPLE
    Get-DevIcon "Rocket"
    Returns "🚀" on PowerShell 7+ or "[START]" on PowerShell 5.1
 
    .EXAMPLE
    $icon = Get-DevIcon "CheckMark"
    Write-Host "$icon Operation completed successfully!"
#>

[CmdletBinding()]
[OutputType([string])]
param(
    [Parameter(Mandatory = $true, Position = 0)]
    [ValidateSet("Rocket", "CheckMark", "Warning", "Info", "Error", "Celebration",
                 "MobilePhone", "Satellite", "Lightning", "Wrench", "Books",
                 "GreenHeart", "Key", "FloppyDisk")]
    [string]$IconName
)

End {
    return Get-ModuleIcon -IconName $IconName
}
}
Function Get-ModuleIcon {
<#
    .SYNOPSIS
    Gets an icon for display based on PowerShell version capabilities
 
    .DESCRIPTION
    Returns either an emoji icon (PowerShell 7+) or plain text fallback (PowerShell 5.1)
 
    .PARAMETER IconName
    The name of the icon to retrieve
 
    .EXAMPLE
    Get-ModuleIcon "Rocket"
    Returns "`u{1F680}" on PowerShell 7+ or "[START]" on PowerShell 5.1
#>

[CmdletBinding()]
[OutputType([string])]
param(
    [Parameter(Mandatory = $true, Position = 0)]
    [string]$IconName,

    [Parameter()]
    [ValidateSet("plaintext", "unicode", "auto")]
    [string]$Mode = "auto"
)

End {
    if ($Mode -eq "plaintext" -or ($Mode -eq "auto" -and -not $script:UseEmojis)) {
        $PlainText = $true
    }
    elseif ($Mode -eq "unicode") {
        $PlainText = $false
    }
    else {
        $PlainText = $script:UseEmojis -eq $false
    }
    if ($PlainText) {
        $IconSet = $script:ModuleIcons.PlainText
    }
    else {
        $IconSet = $script:ModuleIcons
    }
    if ($IconSet.ContainsKey($IconName)) {
        return $IconSet[$IconName]
    }
    else {
        Write-Warning "Icon '$IconName' not found."
    }
    return "?"
}
}
Function Stop-DevProcessOnPort {
<#
    .SYNOPSIS
    Stops processes running on a specific port
 
    .DESCRIPTION
    Finds and forcefully stops all processes that are listening on the specified port.
    Useful for freeing up ports before starting development servers.
 
    .PARAMETER Port
    The port number to free up
 
    .EXAMPLE
    Stop-DevProcessOnPort -Port 8000
    Stops all processes using port 8000
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [int]$Port
)

End {
    try {
        $processes = Get-NetTCPConnection -LocalPort $Port -ErrorAction SilentlyContinue |
                    Select-Object -ExpandProperty OwningProcess -Unique

        foreach ($processId in $processes) {
            if ($processId -and $processId -ne 0) {
                $process = Get-Process -Id $processId -ErrorAction SilentlyContinue
                if ($process) {
                    Write-DevWarning "Stopping process $($process.Name) (PID: $processId) on port $Port"
                    Stop-Process -Id $processId -Force
                    Start-Sleep -Seconds 1
                }
            }
        }
    } catch {
        # Ignore errors when stopping processes
        Write-DevWarning "Could not stop processes on port $Port - they may have already been stopped"
    }
}
}
Function Test-DevCommand {
<#
    .SYNOPSIS
    Tests if a command is available in the current session
 
    .DESCRIPTION
    Checks if a command exists and can be executed in the current PowerShell session
 
    .PARAMETER Command
    The command name to test
 
    .OUTPUTS
    Boolean - True if command exists, False otherwise
 
    .EXAMPLE
    Test-DevCommand "php"
    Returns $true if PHP is available in PATH
#>

[CmdletBinding()]
[OutputType([bool])]
param(
    [Parameter(Mandatory = $true)]
    [string]$Command
)

End {
    try {
        $null = Get-Command $Command -ErrorAction Stop
        return $true
    } catch {
        return $false
    }
}
}
Function Test-DevPort {
<#
    .SYNOPSIS
    Tests if a TCP port is open and accepting connections
 
    .DESCRIPTION
    Uses a TCP client to test if a port is available on localhost (127.0.0.1).
    This approach avoids IPv6 warnings that can occur with Test-NetConnection.
 
    .PARAMETER Port
    The port number to test
 
    .OUTPUTS
    Boolean - True if port is in use, False if available
 
    .EXAMPLE
    Test-DevPort 8000
    Returns $true if port 8000 is in use, $false if available
#>

[CmdletBinding()]
[OutputType([bool])]
param(
    [Parameter(Mandatory = $true)]
    [int]$Port
)

End {
    try {
        # Use a TCP client approach which is more reliable and doesn't show IPv6 warnings
        $tcpClient = New-Object System.Net.Sockets.TcpClient
        $tcpClient.ReceiveTimeout = 1000
        $tcpClient.SendTimeout = 1000
        $result = $tcpClient.BeginConnect("127.0.0.1", $Port, $null, $null)
        $success = $result.AsyncWaitHandle.WaitOne(1000, $false)

        if ($success) {
            try {
                $tcpClient.EndConnect($result)
                $tcpClient.Close()
                return $true
            } catch {
                $tcpClient.Close()
                return $false
            }
        } else {
            $tcpClient.Close()
            return $false
        }
    } catch {
        return $false
    }
}
}
Function Wait-ForDevPort {
<#
    .SYNOPSIS
    Waits for a port to become available (in use) with timeout
 
    .DESCRIPTION
    Continuously tests a port until it becomes available or timeout is reached.
    Useful for waiting for servers to start up.
 
    .PARAMETER Port
    The port number to wait for
 
    .PARAMETER TimeoutSeconds
    Maximum time to wait in seconds (default: 10)
 
    .PARAMETER IntervalSeconds
    Time between checks in seconds (default: 1)
 
    .OUTPUTS
    Boolean - True if port became available within timeout, False otherwise
 
    .EXAMPLE
    Wait-ForDevPort -Port 8000 -TimeoutSeconds 30
    Waits up to 30 seconds for port 8000 to become available
#>

[CmdletBinding()]
[OutputType([bool])]
param(
    [Parameter(Mandatory = $true)]
    [int]$Port,

    [Parameter(Mandatory = $false)]
    [int]$TimeoutSeconds = 10,

    [Parameter(Mandatory = $false)]
    [int]$IntervalSeconds = 1
)

End {
    $elapsed = 0
    while ($elapsed -lt $TimeoutSeconds) {
        if (Test-DevPort -Port $Port) {
            return $true
        }
        Start-Sleep -Seconds $IntervalSeconds
        $elapsed += $IntervalSeconds
    }
    return $false
}
}
Function Write-DevError {
<#
    .SYNOPSIS
    Writes an error message with appropriate icon and color
 
    .DESCRIPTION
    Displays an error message with error icon and red color
 
    .PARAMETER Message
    The message to display
 
    .EXAMPLE
    Write-DevError "Failed to start server"
#>

[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host is appropriate for colored user output in development utilities')]
param(
    [Parameter(Mandatory = $true)]
    [string]$Message
)

End {
    $icon = Get-ModuleIcon "Error"
    Write-Host "$icon $Message" -ForegroundColor $ModuleColorError
}
}
Function Write-DevHeader {
<#
    .SYNOPSIS
    Writes a header message with appropriate icon and color
 
    .DESCRIPTION
    Displays a header message with celebration icon and white color for section headers
 
    .PARAMETER Message
    The message to display
 
    .EXAMPLE
    Write-DevHeader "Starting Laravel Development Environment"
#>

[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host is appropriate for colored user output in development utilities')]
param(
    [Parameter(Mandatory = $true)]
    [string]$Message
)

End {
    $icon = Get-ModuleIcon "Celebration"
    Write-Host ""
    Write-Host "$icon $Message" -ForegroundColor White
    Write-Host ""
}
}
Function Write-DevInfo {
<#
    .SYNOPSIS
    Writes an info message with appropriate icon and color
 
    .DESCRIPTION
    Displays an informational message with info icon and cyan color
 
    .PARAMETER Message
    The message to display
 
    .EXAMPLE
    Write-DevInfo "Found PHP version: 8.2.12"
#>

[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host is appropriate for colored user output in development utilities')]
param(
    [Parameter(Mandatory = $true)]
    [string]$Message
)

End {
    $icon = Get-ModuleIcon "Info"
    Write-Host "$icon $Message" -ForegroundColor $ModuleColorInfo
}
}
Function Write-DevStep {
<#
    .SYNOPSIS
    Writes a step message with appropriate icon and color
 
    .DESCRIPTION
    Displays a step message in the development process with rocket icon and magenta color
 
    .PARAMETER Message
    The message to display
 
    .EXAMPLE
    Write-DevStep "Starting Laravel server..."
#>

[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host is appropriate for colored user output in development utilities')]
param(
    [Parameter(Mandatory = $true)]
    [string]$Message
)

End {
    $icon = Get-ModuleIcon "Rocket"
    Write-Host "$icon $Message" -ForegroundColor $ModuleColorStep
}
}
Function Write-DevSuccess {
<#
    .SYNOPSIS
    Writes a success message with appropriate icon and color
 
    .DESCRIPTION
    Displays a success message with checkmark icon and green color
 
    .PARAMETER Message
    The message to display
 
    .EXAMPLE
    Write-DevSuccess "Server started successfully!"
#>

[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host is appropriate for colored user output in development utilities')]
param(
    [Parameter(Mandatory = $true)]
    [string]$Message
)

End {
    $icon = Get-ModuleIcon "CheckMark"
    Write-Host "$icon $Message" -ForegroundColor $ModuleColorSuccess
}
}
Function Write-DevWarning {
<#
    .SYNOPSIS
    Writes a warning message with appropriate icon and color
 
    .DESCRIPTION
    Displays a warning message with warning icon and yellow color
 
    .PARAMETER Message
    The message to display
 
    .EXAMPLE
    Write-DevWarning "Port is already in use"
#>

[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host is appropriate for colored user output in development utilities')]
param(
    [Parameter(Mandatory = $true)]
    [string]$Message
)

End {
    $icon = Get-ModuleIcon "Warning"
    Write-Host "$icon $Message" -ForegroundColor $ModuleColorWarning
}
}
Function Start-Laravel {
<#
    .SYNOPSIS
    Starts the complete Laravel development environment
 
    .DESCRIPTION
    Starts all Laravel development components: Web server, Vite, and Queue workers
 
    .PARAMETER Path
    The root directory of the Laravel application
 
    .PARAMETER WebPort
    Port for the Laravel web server (default: 8000)
 
    .PARAMETER VitePort
    Port for the Vite development server (default: 5173)
 
    .PARAMETER Queue
    Queue name for Laravel queue workers (default: "default")
 
    .PARAMETER TimeoutSeconds
    Timeout in seconds for server startup checks (default: 30)
 
    .PARAMETER SkipChecks
    Skip port availability checks
 
    .PARAMETER Force
    Force stop any existing processes on the specified ports
 
    .EXAMPLE
    Start-Laravel -Path "C:\path\to\laravel"
    Starts Laravel with default settings (web on 8000, vite on 5173, default queue)
 
    .EXAMPLE
    Start-Laravel -Path "C:\path\to\laravel" -WebPort 8080 -VitePort 3000 -Queue "emails" -Force
    Starts Laravel with custom ports and queue, forcing stop of existing processes
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]$Path,

    [Parameter()]
    [int]$WebPort = 8000,

    [Parameter()]
    [int]$VitePort = 5173,

    [Parameter()]
    [string]$Queue = "default",

    [Parameter()]
    [int]$TimeoutSeconds = 30,

    [Parameter()]
    [switch]$SkipChecks,

    [Parameter()]
    [switch]$Force
)

Begin {
    Write-DevHeader "Starting Laravel Development Environment"

    $success = $true

    try {
        # Start Laravel Web Server
        Write-DevInfo "Starting Laravel web server..."
        $webResult = Start-LaravelWeb -Path $Path -Port $WebPort -TimeoutSeconds $TimeoutSeconds -SkipChecks:$SkipChecks -Force:$Force
        if (-not $webResult) {
            Write-DevError "Failed to start Laravel web server"
            $success = $false
        }

        # Start Vite Development Server
        Write-DevInfo "Starting Vite development server..."
        $viteResult = Start-LaravelVite -Path $Path -Port $VitePort -LaravelPort $WebPort -TimeoutSeconds $TimeoutSeconds -SkipChecks:$SkipChecks -Force:$Force
        if (-not $viteResult) {
            Write-DevError "Failed to start Vite development server"
            $success = $false
        }

        # Start Laravel Queue Worker
        Write-DevInfo "Starting Laravel queue worker..."
        $queueResult = Start-LaravelQueue -Path $Path -Queue $Queue -Force:$Force
        if (-not $queueResult) {
            Write-DevError "Failed to start Laravel queue worker"
            $success = $false
        }

        if ($success) {
            Write-DevSuccess "Laravel development environment started successfully!"
            Write-DevInfo "Services:"
            Write-DevInfo " - Web Server: http://localhost:$WebPort"
            Write-DevInfo " - Vite Server: http://localhost:$VitePort"
            Write-DevInfo " - Queue Worker: $Queue queue"
        } else {
            Write-DevWarning "Some Laravel services failed to start. Check the logs above."
        }

        return $success

    } catch {
        Write-DevError "Failed to start Laravel development environment: $($_.Exception.Message)"
        return $false
    }
}
}
Function Start-LaravelQueue {
<#
    .SYNOPSIS
    Starts the Laravel queue worker
     
    .DESCRIPTION
    Starts Laravel's queue worker to process background jobs
     
    .PARAMETER Path
    The root directory of the Laravel application
     
    .PARAMETER Queue
    The queue name to process (default: default)
     
    .PARAMETER ConnectionName
    The queue connection to use (default: uses Laravel's default)
     
    .PARAMETER MaxJobs
    Maximum number of jobs to process before restarting (default: 1000)
     
    .PARAMETER MaxTime
    Maximum time in seconds the worker should run (default: 3600)
     
    .PARAMETER Sleep
    Number of seconds to sleep when no jobs are available (default: 3)
     
    .PARAMETER Timeout
    Number of seconds a child process can run (default: 60)
     
    .PARAMETER Force
    Force stop any existing queue workers
     
    .EXAMPLE
    Start-LaravelQueue -Path "C:\path\to\laravel"
    Starts Laravel queue worker with default settings
     
    .EXAMPLE
    Start-LaravelQueue -Path "C:\path\to\laravel" -Queue "emails" -MaxJobs 500
    Starts Laravel queue worker for the "emails" queue with max 500 jobs
#>

[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host used for debugging output display in development utility')]
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]$Path,
    
    [Parameter()]
    [string]$Queue = "default",
    
    [Parameter()]
    [string]$ConnectionName,
    
    [Parameter()]
    [int]$MaxJobs = 1000,
    
    [Parameter()]
    [int]$MaxTime = 3600,
    
    [Parameter()]
    [int]$Sleep = 3,
    
    [Parameter()]
    [int]$Timeout = 60,
    
    [Parameter()]
    [switch]$Force
)

Begin {
    Write-DevStep "Starting Laravel queue worker for queue '$Queue'..."
    
    if ($Force) {
        Write-DevInfo "Stopping any existing queue workers..."
        Stop-LaravelQueue -Path $Path -Queue $Queue -Force
    }
    
    # Build the artisan command
    $queueCommand = "queue:work"
    $queueArgs = @()
    
    if ($ConnectionName) {
        $queueArgs += $ConnectionName
    }
    
    $queueArgs += "--queue=$Queue"
    $queueArgs += "--max-jobs=$MaxJobs"
    $queueArgs += "--max-time=$MaxTime"
    $queueArgs += "--sleep=$Sleep"
    $queueArgs += "--timeout=$Timeout"
    $queueArgs += "--verbose"
    
    # Start queue worker
    $queueJob = Start-Job -ScriptBlock {
        Set-Location $Using:Path
        & php artisan $Using:queueCommand $Using:queueArgs
    }
    
    # Give it a moment to start
    Start-Sleep -Seconds 2
    
    # Check if job is running
    if ($queueJob.State -eq "Running") {
        Write-DevSuccess "Laravel queue worker started successfully for queue '$Queue'"
        Write-DevInfo "Worker will process up to $MaxJobs jobs or run for $MaxTime seconds"
        return $queueJob
    } else {
        Write-DevError "Failed to start Laravel queue worker"
        
        # Get job output for debugging
        $jobOutput = Receive-Job $queueJob -ErrorAction SilentlyContinue
        if ($jobOutput) {
            Write-DevError "Queue worker output:"
            Write-Host $jobOutput -ForegroundColor Red
        }
        
        Remove-Job $queueJob -ErrorAction SilentlyContinue
        return $null
    }
}
}
Function Start-LaravelVite {
<#
    .SYNOPSIS
    Starts the Laravel Vite development server
     
    .DESCRIPTION
    Starts the Vite development server for Laravel frontend assets
     
    .PARAMETER Path
    The root directory of the Laravel application
     
    .PARAMETER Port
    The port number to start the Vite server on (default: 5173)
     
    .PARAMETER LaravelPort
    The Laravel web server port for proper integration (default: 8000)
     
    .PARAMETER TimeoutSeconds
    How long to wait for the server to start (default: 15)
     
    .PARAMETER SkipChecks
    Skip port availability checks and start immediately
     
    .PARAMETER Force
    Force stop any existing processes on the specified port
     
    .EXAMPLE
    Start-LaravelVite -Path "C:\path\to\laravel" -Port 5173 -LaravelPort 8000
    Starts Vite server on port 5173 integrated with Laravel on port 8000
#>

[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Path', Justification = 'Used via $Using:Path in Start-Job ScriptBlock')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host used for error output display in development utility')]
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]$Path,
    
    [Parameter()]
    [int]$Port = 5173,
    
    [Parameter()]
    [int]$LaravelPort = 8000,
    
    [Parameter()]
    [int]$TimeoutSeconds = 15,
    
    [Parameter()]
    [switch]$SkipChecks,
    
    [Parameter()]
    [switch]$Force
)

Begin {
    Write-DevStep "Starting Laravel Vite server on port $Port..."
    
    if (-not $SkipChecks) {
        # Check if port is available
        if (Test-DevPort -Port $Port) {
            if ($Force) {
                Write-DevWarning "Port $Port is already in use. Force stopping processes..."
                Stop-DevProcessOnPort -Port $Port
                Start-Sleep -Seconds 2
            } else {
                Write-DevWarning "Port $Port is already in use. Attempting to free it..."
                Stop-DevProcessOnPort -Port $Port
                Start-Sleep -Seconds 2
            }
            
            if (Test-DevPort -Port $Port) {
                Write-DevError "Unable to free port $Port. Please check what's using it and try again."
                return $null
            }
        }
    }
    
    # Start Vite server with output redirection to prevent job termination
    $viteJob = Start-Job -ScriptBlock {
        Set-Location $Using:Path
        
        # Set environment variables for Vite to ensure IPv4 binding
        $env:VITE_PORT = $Using:Port
        $env:VITE_HOST = "127.0.0.1"
        $env:VITE_DEV_SERVER_URL = "http://127.0.0.1:$($Using:Port)"
        
        # Start Vite with port specification using npx directly for proper argument handling
        npx vite --host 127.0.0.1 --port $Using:Port --strictPort 2>&1
    }
    
    if ($SkipChecks) {
        Write-DevInfo "Laravel Vite server started (checks skipped)"
        Write-DevInfo "Note: Access your Vue app via Laravel at http://127.0.0.1:$LaravelPort/"
        return $viteJob
    }
    
    # Wait longer for Vite to start (it takes more time than Laravel)
    Write-DevInfo "Waiting for Laravel Vite server to start (timeout: $TimeoutSeconds seconds)..."
    if (Wait-ForDevPort -Port $Port -TimeoutSeconds $TimeoutSeconds) {
        Write-DevSuccess "Laravel Vite server running at http://127.0.0.1:$Port"
        Write-DevInfo "Note: Access your Vue app via Laravel at http://127.0.0.1:$LaravelPort/"
        return $viteJob
    } else {
        Write-DevError "Failed to start Laravel Vite server within $TimeoutSeconds seconds"
        if ($viteJob) {
            # Get job output for debugging
            Start-Sleep -Seconds 2  # Give job time to produce output
            $jobOutput = Receive-Job $viteJob -ErrorAction SilentlyContinue
            if ($jobOutput) {
                Write-DevError "Vite job output:"
                Write-Host $jobOutput -ForegroundColor Red
            }
            
            # Also check job state and errors
            if ($viteJob.State -eq "Failed") {
                $jobErrors = $viteJob.ChildJobs[0].Error
                if ($jobErrors) {
                    Write-DevError "Vite job errors:"
                    foreach ($err in $jobErrors) {
                        Write-Host $err -ForegroundColor Red
                    }
                }
            }
            
            Stop-Job $viteJob -ErrorAction SilentlyContinue
            Remove-Job $viteJob -ErrorAction SilentlyContinue
        }
        return $null
    }
}
}
Function Start-LaravelWeb {
<#
    .SYNOPSIS
    Starts the Laravel web development server
     
    .DESCRIPTION
    Starts the Laravel artisan serve command on the specified port with proper error handling
     
    .PARAMETER Path
    The root directory of the Laravel application
     
    .PARAMETER Port
    The port number to start the Laravel server on (default: 8000)
     
    .PARAMETER TimeoutSeconds
    How long to wait for the server to start (default: 10)
     
    .PARAMETER SkipChecks
    Skip port availability checks and start immediately
     
    .PARAMETER Force
    Force stop any existing processes on the specified port
     
    .EXAMPLE
    Start-LaravelWeb -Path "C:\path\to\laravel" -Port 8000
    Starts Laravel web server on port 8000
     
    .EXAMPLE
    Start-LaravelWeb -Path "C:\path\to\laravel" -Port 8001 -TimeoutSeconds 15 -SkipChecks
    Starts Laravel web server on port 8001 with 15 second timeout, skipping checks
#>

[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', 'Path', Justification = 'Used via $Using:Path in Start-Job ScriptBlock')]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host used for error output display in development utility')]
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]$Path,
    
    [Parameter()]
    [int]$Port = 8000,
    
    [Parameter()]
    [int]$TimeoutSeconds = 10,
    
    [Parameter()]
    [switch]$SkipChecks,
    
    [Parameter()]
    [switch]$Force
)

Begin {
    Write-DevStep "Starting Laravel web server on port $Port..."
    
    if ($Force -or -not $SkipChecks) {
        # Check if port is available
        if (Test-DevPort -Port $Port) {
            Write-DevWarning "Port $Port is already in use. Attempting to free it..."
            Stop-DevProcessOnPort -Port $Port
            Start-Sleep -Seconds 2
            
            if (Test-DevPort -Port $Port) {
                Write-DevError "Unable to free port $Port. Please check what's using it and try again."
                return $null
            }
        }
    }
    
    # Start Laravel server
    $laravelJob = Start-Job -ScriptBlock {
        Set-Location $Using:Path
        php artisan serve --port=$Using:Port --host=127.0.0.1
    }
    
    if ($SkipChecks) {
        Write-DevInfo "Laravel web server started (checks skipped)"
        return $laravelJob
    }
    
    # Wait for server to start with configurable timeout
    Write-DevInfo "Waiting for Laravel web server to start (timeout: $TimeoutSeconds seconds)..."
    if (Wait-ForDevPort -Port $Port -TimeoutSeconds $TimeoutSeconds) {
        Write-DevSuccess "Laravel web server running at http://127.0.0.1:$Port"
        return $laravelJob
    } else {
        Write-DevError "Failed to start Laravel web server within $TimeoutSeconds seconds"
        
        # Get job output for debugging
        Start-Sleep -Seconds 1
        $jobOutput = Receive-Job $laravelJob -ErrorAction SilentlyContinue
        if ($jobOutput) {
            Write-DevError "Laravel job output:"
            Write-Host $jobOutput -ForegroundColor Red
        }
        
        if ($laravelJob) {
            Stop-Job $laravelJob -ErrorAction SilentlyContinue
            Remove-Job $laravelJob -ErrorAction SilentlyContinue
        }
        return $null
    }
}
}
Function Stop-Laravel {
<#
    .SYNOPSIS
    Stops the complete Laravel development environment
     
    .DESCRIPTION
    Stops all Laravel development components: Web server, Vite, and Queue workers
     
    .PARAMETER Path
    The root directory of the Laravel application
     
    .PARAMETER WebPort
    Port for the Laravel web server (default: 8000)
     
    .PARAMETER VitePort
    Port for the Vite development server (default: 5173)
     
    .PARAMETER Queue
    Queue name for Laravel queue workers (optional - stops all if not specified)
     
    .PARAMETER Force
    Force stop processes without graceful shutdown
     
    .EXAMPLE
    Stop-Laravel -Path "C:\path\to\laravel"
    Stops all Laravel services with default settings
     
    .EXAMPLE
    Stop-Laravel -Path "C:\path\to\laravel" -WebPort 8080 -VitePort 3000 -Queue "emails" -Force
    Forcefully stops Laravel services with custom ports and specific queue
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]$Path,
    
    [Parameter()]
    [int]$WebPort = 8000,
    
    [Parameter()]
    [int]$VitePort = 5173,
    
    [Parameter()]
    [string]$Queue,
    
    [Parameter()]
    [switch]$Force
)

Begin {
    Write-DevHeader "Stopping Laravel Development Environment"
    
    $success = $true
    
    try {
        # Stop Laravel Web Server
        Write-DevInfo "Stopping Laravel web server..."
        $webResult = Stop-LaravelWeb -Path $Path -Port $WebPort -Force:$Force
        if (-not $webResult) {
            Write-DevWarning "Issues stopping Laravel web server"
            $success = $false
        }
        
        # Stop Vite Development Server
        Write-DevInfo "Stopping Vite development server..."
        $viteResult = Stop-LaravelVite -Path $Path -Port $VitePort -Force:$Force
        if (-not $viteResult) {
            Write-DevWarning "Issues stopping Vite development server"
            $success = $false
        }
        
        # Stop Laravel Queue Worker
        Write-DevInfo "Stopping Laravel queue worker..."
        if ($Queue) {
            $queueResult = Stop-LaravelQueue -Path $Path -Queue $Queue -Force:$Force
        } else {
            $queueResult = Stop-LaravelQueue -Path $Path -Force:$Force
        }
        if (-not $queueResult) {
            Write-DevWarning "Issues stopping Laravel queue worker"
            $success = $false
        }
        
        if ($success) {
            Write-DevSuccess "Laravel development environment stopped successfully!"
        } else {
            Write-DevWarning "Some Laravel services may still be running. Check the logs above."
        }
        
        return $success
        
    } catch {
        Write-DevError "Failed to stop Laravel development environment: $($_.Exception.Message)"
        return $false
    }
}
}
Function Stop-LaravelQueue {
<#
    .SYNOPSIS
    Stops the Laravel queue worker
     
    .DESCRIPTION
    Stops Laravel queue worker processes gracefully
     
    .PARAMETER Path
    The root directory of the Laravel application
     
    .PARAMETER Force
    Force stop without confirmation
     
    .PARAMETER Queue
    Specific queue name to target (optional)
     
    .EXAMPLE
    Stop-LaravelQueue -Path "C:\path\to\laravel"
    Stops all Laravel queue workers
     
    .EXAMPLE
    Stop-LaravelQueue -Path "C:\path\to\laravel" -Queue "emails" -Force
    Force stops Laravel queue workers for the "emails" queue
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]$Path,
    
    [Parameter()]
    [switch]$Force,
    
    [Parameter()]
    [string]$Queue
)

Begin {
    Write-DevStep "Stopping Laravel queue worker$(if($Queue) { " for queue '$Queue'" })..."
    
    # Validate Laravel path
    if (-not (Test-Path $Path -PathType Container)) {
        Write-DevError "Laravel path does not exist: $Path"
        return $false
    }
    
    try {
        # Find queue worker processes
        $queueProcesses = Get-Process | Where-Object {
            $_.ProcessName -match "php" -and 
            $_.CommandLine -match "artisan.*queue:work"
        }
        
        if ($Queue) {
            $queueProcesses = $queueProcesses | Where-Object {
                $_.CommandLine -match "queue.*$Queue"
            }
        }
        
        if (-not $queueProcesses) {
            Write-DevInfo "No Laravel queue worker processes found$(if($Queue) { " for queue '$Queue'" })"
            return $true
        }
        
        $stoppedAny = $false
        
        foreach ($process in $queueProcesses) {
            if (-not $Force) {
                $confirmation = Read-Host "Stop Laravel queue worker process (PID: $($process.Id))? [Y/n]"
                if ($confirmation -eq "n" -or $confirmation -eq "N") {
                    Write-DevInfo "Skipping process $($process.Id)"
                    continue
                }
            }
            
            Write-DevStep "Stopping Laravel queue worker process (PID: $($process.Id))"
            
            try {
                # Try graceful stop first
                $process.CloseMainWindow()
                Start-Sleep -Seconds 3
                
                # Check if process is still running
                $runningProcess = Get-Process -Id $process.Id -ErrorAction SilentlyContinue
                if ($runningProcess) {
                    # Force kill if still running
                    Stop-Process -Id $process.Id -Force
                    Start-Sleep -Seconds 1
                }
                
                Write-DevSuccess "Stopped Laravel queue worker (PID: $($process.Id))"
                $stoppedAny = $true
                
            } catch {
                Write-DevError "Failed to stop process $($process.Id)`: $($_.Exception.Message)"
            }
        }
        
        if ($stoppedAny) {
            Write-DevSuccess "Laravel queue worker$(if($Queue) { "s for queue '$Queue'" }) stopped successfully"
            return $true
        } else {
            Write-DevWarning "No Laravel queue workers were stopped"
            return $false
        }
        
    } catch {
        Write-DevError "Failed to stop Laravel queue worker: $($_.Exception.Message)"
        return $false
    }
}
}
Function Stop-LaravelVite {
<#
    .SYNOPSIS
    Stops the Laravel Vite development server
     
    .DESCRIPTION
    Stops processes running on the Laravel Vite server port
     
    .PARAMETER Path
    The root directory of the Laravel application
     
    .PARAMETER Port
    The port number where Laravel Vite server is running (default: 5173)
     
    .PARAMETER Force
    Force stop without confirmation
     
    .EXAMPLE
    Stop-LaravelVite -Path "C:\path\to\laravel" -Port 5173
    Stops Laravel Vite server on port 5173
     
    .EXAMPLE
    Stop-LaravelVite -Path "C:\path\to\laravel" -Force
    Force stops Laravel Vite server with default port
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]$Path,
    
    [Parameter()]
    [int]$Port = 5173,
    
    [Parameter()]
    [switch]$Force
)

Begin {
    Write-DevStep "Stopping Laravel Vite server on port $Port..."
    
    # Validate Laravel path
    if (-not (Test-Path $Path -PathType Container)) {
        Write-DevError "Laravel path does not exist: $Path"
        return $false
    }
    
    try {
        if (-not (Test-DevPort -Port $Port)) {
            Write-DevInfo "Laravel Vite server is not running on port $Port"
            return $true
        }
        
        # Get processes using the port
        $processes = Get-NetTCPConnection -LocalPort $Port -ErrorAction SilentlyContinue | 
                    Select-Object -ExpandProperty OwningProcess -Unique
        
        if (-not $processes) {
            Write-DevWarning "Port $Port appears to be in use but no processes found"
            return $false
        }
        
        $stoppedAny = $false
        
        foreach ($processId in $processes) {
            if ($processId -and $processId -ne 0) {
                $process = Get-Process -Id $processId -ErrorAction SilentlyContinue
                if ($process) {
                    # Verify this is likely a Vite server process
                    $isViteProcess = $process.ProcessName -match "(node|npm)" -or 
                                   $process.CommandLine -match "(vite|npm.*dev)"
                    
                    if ($isViteProcess -or $Force) {
                        if (-not $Force) {
                            $confirmation = Read-Host "Stop Laravel Vite process '$($process.Name)' (PID: $processId)? [Y/n]"
                            if ($confirmation -eq "n" -or $confirmation -eq "N") {
                                Write-DevInfo "Skipping process $processId"
                                continue
                            }
                        }
                        
                        Write-DevStep "Stopping Laravel Vite process '$($process.Name)' (PID: $processId)"
                        
                        try {
                            # Try graceful stop first
                            $process.CloseMainWindow()
                            Start-Sleep -Seconds 2
                            
                            # Check if process is still running
                            $runningProcess = Get-Process -Id $processId -ErrorAction SilentlyContinue
                            if ($runningProcess) {
                                # Force kill if still running
                                Stop-Process -Id $processId -Force
                                Start-Sleep -Seconds 1
                            }
                            
                            Write-DevSuccess "Stopped Laravel Vite server (PID: $processId)"
                            $stoppedAny = $true
                            
                        } catch {
                            Write-DevError "Failed to stop process $processId`: $($_.Exception.Message)"
                        }
                    } else {
                        Write-DevWarning "Process '$($process.Name)' (PID: $processId) on port $Port doesn't appear to be a Laravel Vite server"
                        Write-DevInfo "Use -Force to stop it anyway"
                    }
                }
            }
        }
        
        # Verify port is now free
        Start-Sleep -Seconds 1
        if (-not (Test-DevPort -Port $Port)) {
            if ($stoppedAny) {
                Write-DevSuccess "Laravel Vite server stopped successfully"
            }
            return $true
        } else {
            Write-DevWarning "Laravel Vite port $Port is still in use after attempting to stop processes"
            return $false
        }
        
    } catch {
        Write-DevError "Failed to stop Laravel Vite server on port $Port`: $($_.Exception.Message)"
        return $false
    }
}
}
Function Stop-LaravelWeb {
<#
    .SYNOPSIS
    Stops the Laravel web development server
     
    .DESCRIPTION
    Stops processes running on the Laravel web server port
     
    .PARAMETER Path
    The root directory of the Laravel application
     
    .PARAMETER Port
    The port number where Laravel web server is running (default: 8000)
     
    .PARAMETER Force
    Force stop without confirmation
     
    .EXAMPLE
    Stop-LaravelWeb -Path "C:\path\to\laravel" -Port 8000
    Stops Laravel web server on port 8000
     
    .EXAMPLE
    Stop-LaravelWeb -Path "C:\path\to\laravel" -Port 8001 -Force
    Force stops Laravel web server on port 8001
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]$Path,
    
    [Parameter()]
    [int]$Port = 8000,
    
    [Parameter()]
    [switch]$Force
)

Begin {
    Write-DevStep "Stopping Laravel web server on port $Port..."
    
    # Validate Laravel path
    if (-not (Test-Path $Path -PathType Container)) {
        Write-DevError "Laravel path does not exist: $Path"
        return $false
    }
    
    try {
        if (-not (Test-DevPort -Port $Port)) {
            Write-DevInfo "Laravel web server is not running on port $Port"
            return $true
        }
        
        # Get processes using the port
        $processes = Get-NetTCPConnection -LocalPort $Port -ErrorAction SilentlyContinue | 
                    Select-Object -ExpandProperty OwningProcess -Unique
        
        if (-not $processes) {
            Write-DevWarning "Port $Port appears to be in use but no processes found"
            return $false
        }
        
        $stoppedAny = $false
        
        foreach ($processId in $processes) {
            if ($processId -and $processId -ne 0) {
                $process = Get-Process -Id $processId -ErrorAction SilentlyContinue
                if ($process) {
                    # Verify this is likely a Laravel web server process
                    $isLaravelProcess = $process.ProcessName -match "(php|artisan)" -or 
                                      $process.CommandLine -match "artisan serve"
                    
                    if ($isLaravelProcess -or $Force) {
                        if (-not $Force) {
                            $confirmation = Read-Host "Stop Laravel web process '$($process.Name)' (PID: $processId)? [Y/n]"
                            if ($confirmation -eq "n" -or $confirmation -eq "N") {
                                Write-DevInfo "Skipping process $processId"
                                continue
                            }
                        }
                        
                        Write-DevStep "Stopping Laravel web process '$($process.Name)' (PID: $processId)"
                        
                        try {
                            # Try graceful stop first
                            $process.CloseMainWindow()
                            Start-Sleep -Seconds 2
                            
                            # Check if process is still running
                            $runningProcess = Get-Process -Id $processId -ErrorAction SilentlyContinue
                            if ($runningProcess) {
                                # Force kill if still running
                                Stop-Process -Id $processId -Force
                                Start-Sleep -Seconds 1
                            }
                            
                            Write-DevSuccess "Stopped Laravel web server (PID: $processId)"
                            $stoppedAny = $true
                            
                        } catch {
                            Write-DevError "Failed to stop process $processId`: $($_.Exception.Message)"
                        }
                    } else {
                        Write-DevWarning "Process '$($process.Name)' (PID: $processId) on port $Port doesn't appear to be a Laravel web server"
                        Write-DevInfo "Use -Force to stop it anyway"
                    }
                }
            }
        }
        
        # Verify port is now free
        Start-Sleep -Seconds 1
        if (-not (Test-DevPort -Port $Port)) {
            if ($stoppedAny) {
                Write-DevSuccess "Laravel web server stopped successfully"
            }
            return $true
        } else {
            Write-DevWarning "Laravel web port $Port is still in use after attempting to stop processes"
            return $false
        }
        
    } catch {
        Write-DevError "Failed to stop Laravel web server on port $Port`: $($_.Exception.Message)"
        return $false
    }
}
}
Function Test-Laravel {
<#
    .SYNOPSIS
    Tests if the complete Laravel development environment is running
     
    .DESCRIPTION
    Checks if all Laravel development components are active: Web server, Vite, and Queue workers
     
    .PARAMETER Path
    The root directory of the Laravel application
     
    .PARAMETER WebPort
    Port for the Laravel web server (default: 8000)
     
    .PARAMETER VitePort
    Port for the Vite development server (default: 5173)
     
    .PARAMETER Queue
    Queue name for Laravel queue workers (optional - checks all if not specified)
     
    .EXAMPLE
    Test-Laravel -Path "C:\path\to\laravel"
    Tests all Laravel services with default settings
     
    .EXAMPLE
    Test-Laravel -Path "C:\path\to\laravel" -WebPort 8080 -VitePort 3000 -Queue "emails"
    Tests Laravel services with custom ports and specific queue
#>

[CmdletBinding()]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingWriteHost', '', Justification = 'Write-Host used for status output formatting with spacing in development utility')]
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]$Path,
    
    [Parameter()]
    [int]$WebPort = 8000,
    
    [Parameter()]
    [int]$VitePort = 5173,
    
    [Parameter()]
    [string]$Queue
)

Begin {
    Write-DevHeader "Testing Laravel Development Environment"
    
    $webStatus = $false
    $viteStatus = $false
    $queueStatus = $false
    
    try {
        # Test Laravel Web Server
        Write-DevInfo "Testing Laravel web server..."
        $webStatus = Test-LaravelWeb -Path $Path -Port $WebPort
        
        # Test Vite Development Server
        Write-DevInfo "Testing Vite development server..."
        $viteStatus = Test-LaravelVite -Path $Path -Port $VitePort
        
        # Test Laravel Queue Worker
        Write-DevInfo "Testing Laravel queue worker..."
        if ($Queue) {
            $queueStatus = Test-LaravelQueue -Path $Path -Queue $Queue
        } else {
            $queueStatus = Test-LaravelQueue -Path $Path
        }
        
        # Summary
        Write-Host ""
        Write-DevInfo "Laravel Development Environment Status:"
        Write-DevInfo " - Web Server (port $WebPort): $(if($webStatus) { 'Running' } else { 'Stopped' })"
        Write-DevInfo " - Vite Server (port $VitePort): $(if($viteStatus) { 'Running' } else { 'Stopped' })"
        Write-DevInfo " - Queue Worker$(if($Queue) { " ($Queue)" }): $(if($queueStatus) { 'Running' } else { 'Stopped' })"
        
        $allRunning = $webStatus -and $viteStatus -and $queueStatus
        
        if ($allRunning) {
            Write-DevSuccess "All Laravel services are running!"
        } else {
            $runningCount = @($webStatus, $viteStatus, $queueStatus) | Where-Object { $_ } | Measure-Object | Select-Object -ExpandProperty Count
            Write-DevWarning "$runningCount of 3 Laravel services are running"
        }
        
        return @{
            Web = $webStatus
            Vite = $viteStatus
            Queue = $queueStatus
            All = $allRunning
        }
        
    } catch {
        Write-DevError "Failed to test Laravel development environment: $($_.Exception.Message)"
        return @{
            Web = $false
            Vite = $false
            Queue = $false
            All = $false
        }
    }
}
}
Function Test-LaravelQueue {
<#
    .SYNOPSIS
    Tests if the Laravel queue worker is running
     
    .DESCRIPTION
    Checks if Laravel queue worker processes are active
     
    .PARAMETER Path
    The root directory of the Laravel application
     
    .PARAMETER Queue
    Specific queue name to check (optional)
     
    .EXAMPLE
    Test-LaravelQueue -Path "C:\path\to\laravel"
    Tests if any Laravel queue workers are running
     
    .EXAMPLE
    Test-LaravelQueue -Path "C:\path\to\laravel" -Queue "emails"
    Tests if Laravel queue workers are running for the "emails" queue
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]$Path,
    
    [Parameter()]
    [string]$Queue
)

Begin {
    Write-DevInfo "Testing Laravel queue worker$(if($Queue) { " for queue '$Queue'" })..."
    
    # Validate Laravel path
    if (-not (Test-Path $Path -PathType Container)) {
        Write-DevError "Laravel path does not exist: $Path"
        return $false
    }
    
    try {
        # Find queue worker processes using WMI for more reliable command line detection
        # Note: Using WMI for compatibility with existing tests and broad system support
        $queueProcesses = Get-WmiObject Win32_Process | Where-Object {
            $_.Name -match "php" -and 
            $_.CommandLine -match "artisan.*queue:work"
        }
        
        if ($Queue) {
            $queueProcesses = $queueProcesses | Where-Object {
                $_.CommandLine -match "queue.*$Queue"
            }
        }
        
        if ($queueProcesses) {
            $processCount = $queueProcesses.Count
            Write-DevSuccess "Found $processCount Laravel queue worker process$(if($processCount -gt 1) { 'es' })$(if($Queue) { " for queue '$Queue'" })"
            
            foreach ($process in $queueProcesses) {
                Write-DevInfo " - PID: $($process.ProcessId), Started: $($process.CreationDate)"
            }
            
            return $true
        } else {
            Write-DevInfo "No Laravel queue worker processes found$(if($Queue) { " for queue '$Queue'" })"
            return $false
        }
        
    } catch {
        Write-DevError "Failed to test Laravel queue worker: $($_.Exception.Message)"
        return $false
    }
}
}
Function Test-LaravelVite {
<#
    .SYNOPSIS
    Tests if the Laravel Vite development server is running
     
    .DESCRIPTION
    Checks if the Laravel Vite server is responding on the specified port
     
    .PARAMETER Port
    The port number to test (default: 5173)
     
    .EXAMPLE
    Test-LaravelVite -Port 5173
    Tests if Laravel Vite server is running on port 5173
#>

[CmdletBinding()]
param(
    [Parameter()]
    [int]$Port = 5173
)

Begin {
    Write-DevInfo "Testing Laravel Vite server on port $Port..."
    
    if (Test-DevPort -Port $Port) {
        try {
            # Try to make a simple HTTP request to verify it's actually Vite
            $response = Invoke-WebRequest -Uri "http://127.0.0.1:$Port" -Method HEAD -TimeoutSec 5 -ErrorAction SilentlyContinue
            if ($response) {
                Write-DevSuccess "Laravel Vite server is running and responding on port $Port"
                return $true
            } else {
                Write-DevWarning "Port $Port is in use but not responding to HTTP requests"
                return $false
            }
        } catch {
            Write-DevWarning "Port $Port is in use but HTTP test failed: $($_.Exception.Message)"
            return $false
        }
    } else {
        Write-DevInfo "Laravel Vite server is not running on port $Port"
        return $false
    }
}
}
Function Test-LaravelWeb {
<#
    .SYNOPSIS
    Tests if the Laravel web development server is running
     
    .DESCRIPTION
    Checks if the Laravel web server is responding on the specified port
     
    .PARAMETER Path
    The root directory of the Laravel application
     
    .PARAMETER Port
    The port number to test (default: 8000)
     
    .EXAMPLE
    Test-LaravelWeb -Path "C:\path\to\laravel" -Port 8000
    Tests if Laravel web server is running on port 8000
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ Test-Path $_ -PathType Container })]
    [string]$Path,
    
    [Parameter()]
    [int]$Port = 8000
)

Begin {
    Write-DevInfo "Testing Laravel web server on port $Port..."
    
    # Validate Laravel path
    if (-not (Test-Path $Path -PathType Container)) {
        Write-DevError "Laravel path does not exist: $Path"
        return $false
    }
    
    if (Test-DevPort -Port $Port) {
        try {
            # Try to make a simple HTTP request to verify it's actually Laravel
            $response = Invoke-WebRequest -Uri "http://127.0.0.1:$Port" -Method HEAD -TimeoutSec 5 -ErrorAction SilentlyContinue
            if ($response) {
                Write-DevSuccess "Laravel web server is running and responding on port $Port"
                return $true
            } else {
                Write-DevWarning "Port $Port is in use but not responding to HTTP requests"
                return $false
            }
        } catch {
            Write-DevWarning "Port $Port is in use but HTTP test failed: $($_.Exception.Message)"
            return $false
        }
    } else {
        Write-DevInfo "Laravel web server is not running on port $Port"
        return $false
    }
}
}