# OpenClaw Auto-Login PowerShell Script
# This script follows the "How to connect" steps from the dashboard:
#   1. Start the gateway on your host machine
#   2. Get a tokenized dashboard URL
#   3. Open the browser with the authenticated URL
#
# Usage: .\auto-login.ps1 [-BrowserPath "path\to\browser.exe"]

param(
    [string]$BrowserPath = ""
)

$ErrorActionPreference = "Stop"

Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan

Write-Host "🦞 OpenClaw Auto-Login" -ForegroundColor Cyan
Write-Host "Following the 'How to connect' steps..." -ForegroundColor Gray

Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan -NoNewline
Write-Host "=" -ForegroundColor Cyan

# Get wrapper path (isolated installation)
$InstallBase = "$env:LOCALAPPDATA\openclaw-installer"
$WrapperPath = "$InstallBase\bin\openclaw.cmd"

if (-not (Test-Path $WrapperPath)) {
    Write-Host "❌ OpenClaw wrapper not found at: $WrapperPath" -ForegroundColor Red
    Write-Host "   Please run: openclaw-installer install --config <config.yaml>" -ForegroundColor Yellow
    exit 1
}

Write-Host "Using wrapper: $WrapperPath" -ForegroundColor White

# Function to check gateway status
# Returns: @($isHealthy, $statusMessage)
function Test-GatewayStatus {
    try {
        $result = & $WrapperPath "gateway" "status" 2>&1
        $output = $result -join " "
        
        # Check for RPC probe failure first (gateway crashed)
        if ($output -match "RPC probe: failed") {
            return @($false, "RPC probe failed - gateway may have crashed")
        }
        
        # Check for abnormal closure (WebSocket error)
        if ($output -match "abnormal closure|1006") {
            return @($false, "WebSocket abnormal closure - gateway crashed")
        }
        
        # Best indicator: RPC probe is OK
        if ($output -match "RPC probe: ok") {
            return @($true, "RPC probe OK")
        }
        
        # Other positive indicators
        if ($output -match "running") {
            return @($true, "gateway running")
        }
        if ($output -match "Listening:") {
            return @($true, "port listening")
        }
        if ($output -match "state Ready") {
            return @($true, "state ready")
        }
        if ($output -match "Dashboard: http://") {
            return @($true, "dashboard URL available")
        }
        
        return @($false, "unknown status")
    } catch {
        return @($false, "error: $_")
    }
}

# Function to find process using a port
function Find-ProcessUsingPort($Port = 18789) {
    try {
        $connection = Get-NetTCPConnection -LocalPort $Port -ErrorAction SilentlyContinue | Select-Object -First 1
        if ($connection) {
            $process = Get-Process -Id $connection.OwningProcess -ErrorAction SilentlyContinue
            if ($process) {
                return @($connection.OwningProcess, $process.ProcessName)
            }
        }
    } catch {
        # Fallback: use netstat
        $netstat = netstat -ano | findstr ":$Port"
        if ($netstat) {
            $lines = $netstat -split "`n"
            foreach ($line in $lines) {
                if ($line -match "LISTENING|ESTABLISHED") {
                    $parts = $line -split "\s+" | Where-Object { $_ }
                    if ($parts.Count -ge 5) {
                        $pid = $parts[-1]
                        $proc = Get-Process -Id $pid -ErrorAction SilentlyContinue
                        if ($proc) {
                            return @([int]$pid, $proc.ProcessName)
                        }
                    }
                }
            }
        }
    }
    return $null
}

# Function to resolve port conflicts
function Resolve-PortConflict($Port = 18789, $Force = $true) {
    $procInfo = Find-ProcessUsingPort -Port $Port
    
    if (-not $procInfo) {
        return @($true, "Port $Port is available")
    }
    
    $pid = $procInfo[0]
    $procName = $procInfo[1]
    
    if (-not $Force) {
        return @($false, "Port $Port is in use by $procName (PID: $pid)")
    }
    
    Write-Host "   [INFO] Port $Port is in use by $procName (PID: $pid)" -ForegroundColor Yellow
    Write-Host "   [INFO] Attempting to terminate process..." -ForegroundColor Yellow
    
    try {
        Stop-Process -Id $pid -Force -ErrorAction Stop
        Start-Sleep -Seconds 2
        
        # Verify port is now free
        if (-not (Find-ProcessUsingPort -Port $Port)) {
            return @($true, "Process $procName (PID: $pid) terminated, port $Port is now available")
        } else {
            return @($false, "Process terminated but port $Port is still in use")
        }
    } catch {
        return @($false, "Failed to terminate process $procName (PID: $pid): $_")
    }
}

# Step 1: Check and start gateway
Write-Host ""
Write-Host "Step 1: Checking gateway status..." -ForegroundColor White

$status = Test-GatewayStatus
$isHealthy = $status[0]
$statusMsg = $status[1]

if ($isHealthy) {
    Write-Host "[OK] Gateway is already running ($statusMsg)" -ForegroundColor Green
} else {
    Write-Host "Gateway status: $statusMsg" -ForegroundColor Yellow
    Write-Host "Waiting for gateway to initialize..." -ForegroundColor Yellow
    
    # Wait a bit for gateway to initialize
    $waited = 0
    $maxWait = 10
    $status = Test-GatewayStatus
    while ($waited -lt $maxWait -and -not $status[0]) {
        Start-Sleep -Seconds 1
        $waited++
        if ($waited % 3 -eq 0) {
            Write-Host "  ... waited ${waited}s (status: $($status[1]))" -ForegroundColor Gray
        }
        $status = Test-GatewayStatus
    }
    
    if ($status[0]) {
        Write-Host "[OK] Gateway is now running ($($status[1]))" -ForegroundColor Green
    } else {
        Write-Host "Gateway not responding: $($status[1])" -ForegroundColor Yellow
        Write-Host "Attempting to start gateway..." -ForegroundColor Yellow
        
        # Check and resolve port conflicts
        $portStatus = Resolve-PortConflict -Port 18789 -Force $true
        if ($portStatus[0]) {
            Write-Host "   [OK] $($portStatus[1])" -ForegroundColor Green
        } else {
            Write-Host "   [WARNING] $($portStatus[1])" -ForegroundColor Yellow
            Write-Host "   [WARNING] Attempting to start anyway..." -ForegroundColor Yellow
        }
        
        # Try to start gateway using direct Node.js command (most reliable)
        $NodePath = "$env:USERPROFILE\AppData\Local\openclaw-installer\node\node.exe"
        $IndexPath = "$env:USERPROFILE\AppData\Local\openclaw-installer\openclaw\node_modules\openclaw\dist\index.js"
        
        Write-Host "   [INFO] Using direct Node.js command..." -ForegroundColor Gray
        Write-Host "   [INFO] Node: $NodePath" -ForegroundColor Gray
        Write-Host "   [INFO] Index: $IndexPath" -ForegroundColor Gray
        
        # Start gateway directly: node index.js gateway --port 18789
        Start-Process -FilePath $NodePath -ArgumentList "`"$IndexPath`"", "gateway", "--port", "18789" -WindowStyle Hidden
        
        # Retry with increasing delays
        $retryDelays = @(2, 4, 6)
        foreach ($delay in $retryDelays) {
            Write-Host "  Waiting ${delay}s for gateway to initialize..." -ForegroundColor Gray
            Start-Sleep -Seconds $delay
            $status = Test-GatewayStatus
            if ($status[0]) {
                Write-Host "[OK] Gateway started successfully ($($status[1]))" -ForegroundColor Green
                break
            }
        }
            
            # Wait longer for foreground process
            $waited = 0
            $maxWait = 30
            while ($waited -lt $maxWait -and -not $status[0]) {
                Start-Sleep -Seconds 2
                $waited += 2
                if ($waited % 5 -eq 0) {
                    Write-Host "  ... waited ${waited}s (status: $($status[1]))" -ForegroundColor Gray
                }
                $status = Test-GatewayStatus
            }
            
            if ($status[0]) {
                Write-Host "[OK] Gateway is now running ($($status[1]))" -ForegroundColor Green
            } else {
                Write-Host "[WARNING] Gateway may still be starting ($($status[1])), continuing anyway..." -ForegroundColor Yellow
                # Don't fail - the dashboard URL might still work
            }
        }
    }
}

# Step 2: Get tokenized URL
Write-Host ""
Write-Host "Step 2: Getting authenticated dashboard URL..." -ForegroundColor White

$dashboardOutput = & $WrapperPath "dashboard" "--no-open" 2>&1
$DashboardUrl = $null

# Parse URL from output
foreach ($line in $dashboardOutput -split "`n") {
    if ($line -match "(https?://[^\s]+)") {
        $DashboardUrl = $matches[1]
        break
    }
}

if (-not $DashboardUrl) {
    Write-Host "[WARNING] Could not get tokenized URL, using default..." -ForegroundColor Yellow
    $DashboardUrl = "http://127.0.0.1:18789/"
} else {
    Write-Host "[OK] Got authenticated URL" -ForegroundColor Green
}

# Step 3: Open browser
Write-Host ""
Write-Host "Step 3: Opening dashboard..." -ForegroundColor White

try {
    if ($BrowserPath -and (Test-Path $BrowserPath)) {
        Start-Process -FilePath $BrowserPath -ArgumentList $DashboardUrl
    } else {
        Start-Process $DashboardUrl
    }
    
    Write-Host ""
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green
    
    Write-Host "[SUCCESS] Dashboard is now open in your browser." -ForegroundColor Green
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green -NoNewline
    Write-Host "=" -ForegroundColor Green
    
    Write-Host ""
    Write-Host "The dashboard is now logged in automatically." -ForegroundColor Cyan
    Write-Host "No manual token entry needed!" -ForegroundColor Gray
} catch {
    Write-Host "❌ Failed to open browser: $_" -ForegroundColor Red
    Write-Host "   Please manually open: $DashboardUrl" -ForegroundColor Yellow
}
