#!/usr/bin/env bash
# redeploy_all_cpp_apps — Cross-compila TODOS los apps C++ del registry en un solo
# cmake pass y despliega cada .exe al Desktop de Windows.
# Uso: redeploy_all_cpp_apps [filter]
#   filter  substring opcional para limitar el deploy a apps cuyo nombre lo contenga
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../infra/build_cpp_windows.sh"
source "$SCRIPT_DIR/../infra/deploy_cpp_exe_to_windows.sh"

redeploy_all_cpp_apps() {
    local filter="${1:-}"

    # --- Localizar raiz del registry ---
    local root="${FN_REGISTRY_ROOT:-}"
    if [ -z "$root" ]; then
        local d="$SCRIPT_DIR"
        while [ "$d" != "/" ]; do
            if [ -f "$d/registry.db" ] && [ -d "$d/cpp" ]; then
                root="$d"; break
            fi
            d="$(dirname "$d")"
        done
    fi
    if [ -z "$root" ]; then
        echo "[redeploy_all_cpp_apps] ERROR: no se localiza la raiz del registry. Exporta FN_REGISTRY_ROOT." >&2
        return 2
    fi

    local build_win="${BUILD_WIN:-$root/cpp/build/windows}"

    # --- Paso 1: compilar TODO el arbol (un solo cmake pass) ---
    # Tolerante a fallos: si algun target (ej. test_* roto en mingw, app con
    # bug puntual) falla, los demas exes que SI se construyeron siguen siendo
    # desplegables. El loop de deploy hace SKIP por cada app sin .exe, asi que
    # el modo "build best-effort + deploy lo que haya" es seguro.
    echo "[1/2] Cross-compiling all C++ targets (best-effort)..."
    local build_rc=0
    build_cpp_windows || build_rc=$?
    if [ "$build_rc" -ne 0 ]; then
        echo "[1/2] Build returned exit=$build_rc — continuing with deploy of available exes" >&2
    else
        echo "[1/2] Build OK"
    fi

    # --- Descubrir apps con CMakeLists.txt ---
    # Busca en apps/*/ y projects/*/apps/*/ (no en cpp/apps/ — deprecado)
    local -a app_dirs=()
    while IFS= read -r cmakelists; do
        app_dirs+=("$(dirname "$cmakelists")")
    done < <(
        find "$root/apps" -maxdepth 2 -name "CMakeLists.txt" 2>/dev/null | sort
        find "$root/projects" -maxdepth 4 -path "*/apps/*/CMakeLists.txt" 2>/dev/null | sort
    )

    if [ ${#app_dirs[@]} -eq 0 ]; then
        echo "[redeploy_all_cpp_apps] WARN: no se encontraron apps con CMakeLists.txt" >&2
        return 0
    fi

    # --- Paso 2: deploy por app ---
    echo "[2/2] Deploying apps to Windows Desktop..."
    local -a ok=() skipped=() failed=()

    for app_dir in "${app_dirs[@]}"; do
        local name
        name="$(basename "$app_dir")"

        # Aplicar filtro si se indico
        if [ -n "$filter" ] && [[ "$name" != *"$filter"* ]]; then
            continue
        fi

        # Localizar el .exe en la ubicacion canonica
        local exe_path="$build_win/apps/$name/$name.exe"
        if [ ! -f "$exe_path" ]; then
            # Fallback: buscar bajo build_win/
            exe_path="$(find "$build_win" -name "$name.exe" -type f 2>/dev/null | head -n1 || true)"
        fi

        if [ -z "$exe_path" ] || [ ! -f "$exe_path" ]; then
            echo "  SKIP: $name — .exe no encontrado en $build_win" >&2
            skipped+=("$name")
            continue
        fi

        # taskkill silencioso (pre-autorizado; deploy_cpp_exe_to_windows lo hace internamente,
        # pero si deploy falla antes de llegar ahi nos aseguramos de liberar el lock)
        if command -v taskkill.exe >/dev/null 2>&1; then
            taskkill.exe /IM "${name}.exe" /F >/dev/null 2>&1 || true
        fi

        if deploy_cpp_exe_to_windows "$name" "$app_dir"; then
            ok+=("$name")
        else
            echo "  FAILED: $name" >&2
            failed+=("$name")
        fi
    done

    # --- Resumen ---
    echo ""
    echo "===== redeploy_all_cpp_apps — summary ====="
    printf "  OK      : %d\n" "${#ok[@]}"
    printf "  SKIPPED : %d\n" "${#skipped[@]}"
    printf "  FAILED  : %d\n" "${#failed[@]}"

    if [ ${#ok[@]} -gt 0 ]; then
        echo "  Deployed:"
        for n in "${ok[@]}"; do printf "    + %s\n" "$n"; done
    fi
    if [ ${#skipped[@]} -gt 0 ]; then
        echo "  Skipped (no .exe):"
        for n in "${skipped[@]}"; do printf "    - %s\n" "$n"; done
    fi
    if [ ${#failed[@]} -gt 0 ]; then
        echo "  Failed:"
        for n in "${failed[@]}"; do printf "    x %s\n" "$n"; done
        return 1
    fi
}

# Ejecutar si se llama directamente (fn run lo invoca como script)
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    redeploy_all_cpp_apps "$@"
fi
