#!/usr/bin/env bash
# adb_wsl — Wrapper sourceable para resolver e invocar adb.
# Linux-first: usa el adb nativo del Android SDK o del PATH. Conserva un
# fallback a adb.exe SOLO cuando se detecta WSL2 (legacy). El nombre del
# archivo se mantiene por compatibilidad con sus consumidores del registry.
# Uso: source bash/functions/infra/adb_wsl.sh
# Smoke test: bash bash/functions/infra/adb_wsl.sh --self-test

# ---------------------------------------------------------------------------
# Resolver ADB (Linux-first; fallback WSL legacy)
# ---------------------------------------------------------------------------
# Prioridad de resolucion:
#   1. $ADB preexportada por el caller (override explicito).
#   2. adb nativo del Android SDK ($ANDROID_HOME / $ANDROID_SDK_ROOT).
#   3. adb del PATH.
#   4. (legacy) adb.exe de Windows, solo si corremos dentro de WSL2.
if [[ -z "${ADB:-}" ]]; then
    _sdk="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-}}"
    if [[ -n "$_sdk" && -x "$_sdk/platform-tools/adb" ]]; then
        ADB="$_sdk/platform-tools/adb"
    elif command -v adb &>/dev/null; then
        ADB="$(command -v adb)"
    elif grep -qiE "(microsoft|wsl)" /proc/version 2>/dev/null; then
        _sdk_win="${ANDROID_SDK_WIN:-/mnt/c/Users/$USER/AppData/Local/Android/Sdk}"
        ADB="${_sdk_win}/platform-tools/adb.exe"
        unset _sdk_win
    fi
    unset _sdk
fi

if [[ -z "${ADB:-}" ]] || ! command -v "$ADB" &>/dev/null; then
    echo "adb_wsl: adb no encontrado. Instala el SDK (fn run install_android_sdk_bash_infra), exporta ANDROID_HOME, o fija ADB= antes de sourcear." >&2
    # Solo abortamos si el script se ejecuta directamente; si se sourcea,
    # permitimos continuar para que el caller maneje el error.
    return 1 2>/dev/null || exit 1
fi

# ---------------------------------------------------------------------------
# adb_run "<args...>"
# Ejecuta adb (el binario resuelto en $ADB) con los argumentos dados.
# Retorna el exit code de adb.
# ---------------------------------------------------------------------------
adb_run() {
    "$ADB" "$@"
}

# ---------------------------------------------------------------------------
# adb_devices
# Lista dispositivos ADB conectados.
# ---------------------------------------------------------------------------
adb_devices() {
    adb_run devices
}

# ---------------------------------------------------------------------------
# adb_wsl_to_win <path_wsl>
# Convierte un path WSL a formato Windows usando wslpath.
# Si wslpath no está disponible retorna el path tal cual.
# ---------------------------------------------------------------------------
adb_wsl_to_win() {
    local path_wsl="$1"
    if command -v wslpath &>/dev/null; then
        wslpath -w "$path_wsl"
    else
        echo "$path_wsl"
    fi
}

# ---------------------------------------------------------------------------
# adb_wait_boot [timeout_s]
# Espera a que el dispositivo/emulador complete el boot (sys.boot_completed=1).
# timeout_s: segundos máximos de espera (default 120).
# Retorna 0 si boot completado, 1 si timeout.
# ---------------------------------------------------------------------------
adb_wait_boot() {
    local timeout_s="${1:-120}"
    local elapsed=0
    local interval=3

    while (( elapsed < timeout_s )); do
        local val
        val=$(adb_run shell getprop sys.boot_completed 2>/dev/null | tr -d '[:space:]')
        if [[ "$val" == "1" ]]; then
            return 0
        fi
        sleep "$interval"
        (( elapsed += interval ))
    done

    echo "adb_wsl: timeout ${timeout_s}s esperando boot del dispositivo." >&2
    return 1
}

# ---------------------------------------------------------------------------
# adb_pick_serial [--serial <S>] [...]
# Resuelve el serial a usar para multi-device. Lee --serial X de los args.
# Setea globals ADB_PICK_SERIAL y ADB_PICK_REST (no usa stdout para evitar
# perder los globals via subshell de $()).
# Exit 1 si no hay device disponible.
#
# Uso tipico:
#   adb_pick_serial "$@" || { echo "no device" >&2; exit 3; }
#   local serial="$ADB_PICK_SERIAL"
#   set -- "${ADB_PICK_REST[@]}"
# ---------------------------------------------------------------------------
adb_pick_serial() {
    ADB_PICK_SERIAL="${ADB_SERIAL:-}"
    ADB_PICK_REST=()
    while [[ $# -gt 0 ]]; do
        case "$1" in
            --serial) ADB_PICK_SERIAL="$2"; shift 2 ;;
            --serial=*) ADB_PICK_SERIAL="${1#--serial=}"; shift ;;
            *) ADB_PICK_REST+=("$1"); shift ;;
        esac
    done
    if [[ -z "$ADB_PICK_SERIAL" ]]; then
        ADB_PICK_SERIAL=$(adb_run devices 2>/dev/null | awk '/(emulator-|device$)/ && !/List of/ {print $1; exit}')
    fi
    if [[ -z "$ADB_PICK_SERIAL" ]]; then
        echo "adb_wsl: ningun device/emulador conectado." >&2
        return 1
    fi
    if ! adb_run devices 2>/dev/null | awk '{print $1}' | grep -qx "$ADB_PICK_SERIAL"; then
        echo "adb_wsl: serial '$ADB_PICK_SERIAL' no encontrado en adb devices." >&2
        return 1
    fi
    return 0
}

# ---------------------------------------------------------------------------
# adb_s <serial> <args...>
# Atajo: adb_run -s <serial> <args...>
# ---------------------------------------------------------------------------
adb_s() {
    local serial="$1"; shift
    adb_run -s "$serial" "$@"
}

# ---------------------------------------------------------------------------
# Smoke test (solo si invocado directamente con --self-test)
# ---------------------------------------------------------------------------
if [[ "${1:-}" == "--self-test" ]]; then
    adb_run version || exit 1
    echo "OK"
fi
