#!/usr/bin/env bash
# focus_cdp_tab_window — trae al frente la pestaña + la ventana del SO de un Chrome con CDP
#
# Handoff humano de captcha: activa la tab del captcha (opcional, via CDP) y levanta
# la ventana X11 del proceso browser principal de ese puerto para que un humano resuelva
# el captcha a mano. Best-effort y robusto: cada paso continua aunque uno falle.

focus_cdp_tab_window() {
    set -uo pipefail

    local port="${1:-}"
    local target_id="${2:-}"

    # 1. Validacion de entorno y dependencias.
    if [[ -z "$port" ]]; then
        echo "focus_cdp_tab_window: falta el puerto CDP (uso: focus_cdp_tab_window <port> [target_id])" >&2
        return 2
    fi
    if [[ -z "${DISPLAY:-}" ]]; then
        echo "focus_cdp_tab_window: sin entorno grafico (DISPLAY vacio)" >&2
        return 3
    fi
    if ! command -v wmctrl >/dev/null 2>&1 || ! command -v xdotool >/dev/null 2>&1; then
        echo "focus_cdp_tab_window: falta wmctrl/xdotool" >&2
        return 4
    fi

    # 2. Activar la tab del captcha dentro del browser (best-effort, no aborta).
    if [[ -n "$target_id" ]]; then
        curl -sf "http://127.0.0.1:${port}/json/activate/${target_id}" >/dev/null 2>&1 || true
    fi

    # 3. Encontrar el PID del proceso BROWSER principal de ese puerto.
    #    De las lineas que matchean el flag de debugging, el browser process es el que
    #    NO lleva --type= (los renderers/gpu/utility/zygote son procesos hijos).
    local browser_pid=""
    local line
    while IFS= read -r line; do
        [[ -z "$line" ]] && continue
        if [[ "$line" == *"--type="* ]]; then
            continue
        fi
        # pgrep -af antepone el PID seguido de la cmdline.
        browser_pid="${line%% *}"
        break
    done < <(pgrep -af -- "remote-debugging-port=${port}" 2>/dev/null)

    if [[ -z "$browser_pid" ]]; then
        echo "focus_cdp_tab_window: no hay chromium en el puerto ${port}" >&2
        return 5
    fi

    # 4. Resolver el window id top-level.
    #    Primero por wmctrl -lp (columna 3 = PID). Fallback xdotool si el main no expone _NET_WM_PID.
    local wid=""
    while IFS= read -r line; do
        [[ -z "$line" ]] && continue
        # Formato: <wid> <desktop> <pid> <host> <title...>
        local w_id w_pid
        w_id="$(awk '{print $1}' <<<"$line")"
        w_pid="$(awk '{print $3}' <<<"$line")"
        if [[ "$w_pid" == "$browser_pid" ]]; then
            wid="$w_id"
            break
        fi
    done < <(wmctrl -lp 2>/dev/null)

    if [[ -z "$wid" ]]; then
        wid="$(xdotool search --pid "$browser_pid" --onlyvisible 2>/dev/null | head -n1)"
    fi

    if [[ -z "$wid" ]]; then
        echo "focus_cdp_tab_window: no se encontro ventana top-level para pid ${browser_pid} (puerto ${port})" >&2
        return 6
    fi

    # 5. Traer al frente con REINTENTO (xfwm de XFCE pisa el primer activate/raise).
    #    Espera no bloqueante con read -t en vez de sleep.
    local attempt
    for attempt in 1 2; do
        xdotool windowactivate "$wid" >/dev/null 2>&1 || true
        read -r -t 0.2 _ < /dev/zero 2>/dev/null || true
        xdotool windowraise "$wid" >/dev/null 2>&1 || true
    done

    # 6. Salida legible y JSON-parseable simple.
    echo "focus_cdp_tab_window: focused win=${wid} pid=${browser_pid} port=${port} tab=${target_id:--}"
    return 0
}

# Permitir ejecucion directa: focus_cdp_tab_window <port> [target_id]
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    focus_cdp_tab_window "$@"
fi
