#!/usr/bin/env bash
# OpenClaw Auto-Login Bash 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.sh [-b /path/to/browser]

set -e

# Parse arguments
BROWSER_PATH=""
while [[ $# -gt 0 ]]; do
    case $1 in
        -b|--browser)
            BROWSER_PATH="$2"
            shift 2
            ;;
        *)
            shift
            ;;
    esac
done

echo "============================================================"
echo "OpenClaw Auto-Login"
echo "Following the 'How to connect' steps..."
echo "============================================================"

# Get wrapper path (isolated installation)
# Use XDG_DATA_HOME if set, otherwise default to ~/.local/share
if [[ -n "$XDG_DATA_HOME" ]]; then
    INSTALL_BASE="$XDG_DATA_HOME/openclaw-installer"
else
    INSTALL_BASE="$HOME/.local/share/openclaw-installer"
fi
WRAPPER_PATH="$INSTALL_BASE/bin/openclaw"

if [[ ! -f "$WRAPPER_PATH" ]]; then
    echo "[ERROR] OpenClaw wrapper not found at: $WRAPPER_PATH"
    echo "   Please run: openclaw-installer install --config <config.yaml>"
    exit 1
fi

echo "Using wrapper: $WRAPPER_PATH"

# Function to check gateway status
# Sets GATEWAY_STATUS_MSG and returns 0 if healthy, 1 if not
check_gateway() {
    local output
    output=$($WRAPPER_PATH gateway status 2>&1)
    
    # Check for RPC probe failure first (gateway crashed)
    if echo "$output" | grep -q "RPC probe: failed"; then
        GATEWAY_STATUS_MSG="RPC probe failed - gateway may have crashed"
        return 1
    fi
    
    # Check for abnormal closure (WebSocket error)
    if echo "$output" | grep -q "abnormal closure"; then
        GATEWAY_STATUS_MSG="WebSocket abnormal closure - gateway crashed"
        return 1
    fi
    
    # Best indicator: RPC probe is OK
    if echo "$output" | grep -q "RPC probe: ok"; then
        GATEWAY_STATUS_MSG="RPC probe OK"
        return 0
    fi
    
    # Other positive indicators
    if echo "$output" | grep -qi "running"; then
        GATEWAY_STATUS_MSG="gateway running"
        return 0
    fi
    if echo "$output" | grep -q "Listening:"; then
        GATEWAY_STATUS_MSG="port listening"
        return 0
    fi
    if echo "$output" | grep -qi "state Ready"; then
        GATEWAY_STATUS_MSG="state ready"
        return 0
    fi
    if echo "$output" | grep -q "Dashboard: http://"; then
        GATEWAY_STATUS_MSG="dashboard URL available"
        return 0
    fi
    
    GATEWAY_STATUS_MSG="unknown status"
    return 1
}

# Function to find process using a port
# Sets PORT_PID and PORT_PROC_NAME if found
find_process_using_port() {
    local port=$1
    PORT_PID=""
    PORT_PROC_NAME=""
    
    if [[ "$OSTYPE" == "darwin"* ]]; then
        # macOS: use lsof
        local output
        output=$(lsof -i ":$port" -P -n 2>/dev/null | grep LISTEN | head -1)
        if [[ -n "$output" ]]; then
            PORT_PID=$(echo "$output" | awk '{print $2}')
            PORT_PROC_NAME=$(echo "$output" | awk '{print $1}')
        fi
    else
        # Linux: try ss first
        local output
        output=$(ss -tlnp "sport = :$port" 2>/dev/null | grep LISTEN | head -1)
        if [[ -n "$output" ]]; then
            # Extract pid from users:(("procname",pid=1234,...))
            if [[ "$output" =~ pid=([0-9]+) ]]; then
                PORT_PID="${BASH_REMATCH[1]}"
            fi
            if [[ "$output" =~ \"([^\"]+)\" ]]; then
                PORT_PROC_NAME="${BASH_REMATCH[1]}"
            fi
        else
            # Fallback to netstat
            output=$(netstat -tlnp 2>/dev/null | grep ":$port ")
            if [[ -n "$output" ]]; then
                local pid_prog
                pid_prog=$(echo "$output" | awk '{print $7}')
                if [[ "$pid_prog" =~ ^([0-9]+)/(.+)$ ]]; then
                    PORT_PID="${BASH_REMATCH[1]}"
                    PORT_PROC_NAME="${BASH_REMATCH[2]}"
                fi
            fi
        fi
    fi
    
    [[ -n "$PORT_PID" ]]
}

# Function to kill a process by PID
kill_process() {
    local pid=$1
    if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "cygwin" || "$OSTYPE" == "win32" ]]; then
        # Windows (via Git Bash or similar)
        taskkill /F /PID "$pid" 2>/dev/null
    else
        # Unix
        kill "$pid" 2>/dev/null
        sleep 1
        # Check if still running
        if kill -0 "$pid" 2>/dev/null; then
            kill -9 "$pid" 2>/dev/null
        fi
    fi
}

# Function to resolve port conflicts
# Returns 0 if resolved/port available, 1 if not
resolve_port_conflict() {
    local port=${1:-18789}
    local force=${2:-true}
    
    if ! find_process_using_port "$port"; then
        echo "Port $port is available"
        return 0
    fi
    
    if [[ "$force" != "true" ]]; then
        echo "Port $port is in use by $PORT_PROC_NAME (PID: $PORT_PID)"
        return 1
    fi
    
    echo "   [INFO] Port $port is in use by $PORT_PROC_NAME (PID: $PORT_PID)"
    echo "   [INFO] Attempting to terminate process..."
    
    if kill_process "$PORT_PID"; then
        sleep 2
        if ! find_process_using_port "$port"; then
            echo "Process $PORT_PROC_NAME (PID: $PORT_PID) terminated, port $port is now available"
            return 0
        else
            echo "Process terminated but port $port is still in use"
            return 1
        fi
    else
        echo "Failed to terminate process $PORT_PROC_NAME (PID: $PORT_PID)"
        return 1
    fi
}

# Step 1: Check and start gateway
echo ""
echo "Step 1: Checking gateway status..."

if check_gateway; then
    echo "[OK] Gateway is already running ($GATEWAY_STATUS_MSG)"
else
    echo "Gateway status: $GATEWAY_STATUS_MSG"
    echo "Waiting for gateway to initialize..."
    
    # Wait a bit for gateway to initialize
    waited=0
    max_wait=10
    while [ $waited -lt $max_wait ] && ! check_gateway; do
        sleep 1
        waited=$((waited + 1))
        if [ $((waited % 3)) -eq 0 ]; then
            echo "  ... waited ${waited}s (status: $GATEWAY_STATUS_MSG)"
        fi
    done
    
    if check_gateway; then
        echo "[OK] Gateway is now running ($GATEWAY_STATUS_MSG)"
    else
        echo "Gateway not responding: $GATEWAY_STATUS_MSG"
        echo "Attempting to start gateway..."
        
        # Check and resolve port conflicts
        port_msg=$(resolve_port_conflict 18789 true)
        if [[ $? -eq 0 ]]; then
            echo "   [OK] $port_msg"
        else
            echo "   [WARNING] $port_msg"
            echo "   [WARNING] Attempting to start anyway..."
        fi
        
        # Try to start gateway using direct Node.js command (most reliable)
        if [[ "$OSTYPE" == "darwin"* ]]; then
            # macOS
            NODE_PATH="$HOME/.local/openclaw-installer/node/bin/node"
            INDEX_PATH="$HOME/.local/openclaw-installer/openclaw/node_modules/openclaw/dist/index.js"
        else
            # Linux
            NODE_PATH="$HOME/.local/openclaw-installer/node/bin/node"
            INDEX_PATH="$HOME/.local/openclaw-installer/openclaw/node_modules/openclaw/dist/index.js"
        fi
        
        echo "   [INFO] Using direct Node.js command..."
        echo "   [INFO] Node: $NODE_PATH"
        echo "   [INFO] Index: $INDEX_PATH"
        
        # Start gateway directly: node index.js gateway --port 18789
        nohup "$NODE_PATH" "$INDEX_PATH" gateway --port 18789 > /dev/null 2>&1 &
        
        # Retry with increasing delays
        for delay in 2 4 6; do
            echo "  Waiting ${delay}s for gateway to initialize..."
            sleep $delay
            if check_gateway; then
                echo "[OK] Gateway started successfully ($GATEWAY_STATUS_MSG)"
                break
            fi
        done
            
            # Wait longer for foreground process
            waited=0
            max_wait=30
            while [ $waited -lt $max_wait ] && ! check_gateway; do
                sleep 2
                waited=$((waited + 2))
                if [ $((waited % 5)) -eq 0 ]; then
                    echo "  ... waited ${waited}s (status: $GATEWAY_STATUS_MSG)"
                fi
            done
            
            if check_gateway; then
                echo "[OK] Gateway is now running ($GATEWAY_STATUS_MSG)"
            else
                echo "[WARNING] Gateway may still be starting ($GATEWAY_STATUS_MSG), continuing anyway..."
                # Don't fail - the dashboard URL might still work
            fi
        fi
    fi
fi

# Step 2: Get tokenized URL
echo ""
echo "Step 2: Getting authenticated dashboard URL..."

DASHBOARD_OUTPUT=$($WRAPPER_PATH dashboard --no-open 2>&1)
DASHBOARD_URL=$(echo "$DASHBOARD_OUTPUT" | grep -oE 'https?://[^[:space:]]+' | head -1)

if [[ -z "$DASHBOARD_URL" ]]; then
    echo "[WARNING] Could not get tokenized URL, using default..."
    DASHBOARD_URL="http://127.0.0.1:18789/"
else
    echo "[OK] Got authenticated URL"
fi

# Step 3: Open browser
echo ""
echo "Step 3: Opening dashboard..."

# Try to open browser in order of preference
BROWSER_OPENED=false

if [[ -n "$BROWSER_PATH" && -f "$BROWSER_PATH" ]]; then
    # User-specified browser
    "$BROWSER_PATH" "$DASHBOARD_URL" &
    BROWSER_OPENED=true
elif [[ "$OSTYPE" == "darwin"* ]]; then
    # macOS: use 'open' command
    open "$DASHBOARD_URL"
    BROWSER_OPENED=true
elif command -v xdg-open &> /dev/null; then
    # Linux: use xdg-open
    xdg-open "$DASHBOARD_URL"
    BROWSER_OPENED=true
elif command -v gnome-open &> /dev/null; then
    # GNOME fallback
    gnome-open "$DASHBOARD_URL"
    BROWSER_OPENED=true
elif command -v kde-open &> /dev/null; then
    # KDE fallback
    kde-open "$DASHBOARD_URL"
    BROWSER_OPENED=true
else
    # Last resort: python webbrowser
    python3 -c "import webbrowser; webbrowser.open('$DASHBOARD_URL')" 2>/dev/null || \
    python -c "import webbrowser; webbrowser.open('$DASHBOARD_URL')" 2>/dev/null || true
    BROWSER_OPENED=true
fi

if [[ "$BROWSER_OPENED" != true ]]; then
    echo "❌ Could not detect browser. Please manually open: $DASHBOARD_URL"
    exit 1
fi

echo ""
echo "============================================================"
echo "[SUCCESS] Dashboard is now open in your browser."
echo "============================================================"
echo ""
echo "The dashboard is now logged in automatically."
echo "No manual token entry needed!"

