#!/usr/bin/env bash
# run_kotlin_app_tests — Pipeline e2e completo de testing app Kotlin:
#   unit JVM + screenshot Roborazzi + build APK + instrumented Compose en emulador.
#
# USO:
#   bash run_kotlin_app_tests.sh <project_dir> [avd_name] [--skip-emulator] [--no-stop]
#
# ARGUMENTOS:
#   project_dir      Raiz del proyecto Android (debe contener gradlew). Obligatorio.
#   avd_name         Nombre del AVD para instrumented tests. Default: Medium_Phone_API_35.
#   --skip-emulator  Saltar instrumented tests (solo unit + screenshot + build).
#   --no-stop        No parar el emulador al finalizar (util en desarrollo iterativo).
#
# EXIT CODES:
#   0  Todos los tests pasan.
#   1  Unit tests fallaron.
#   2  Screenshot tests fallaron.
#   3  Build APK fallado.
#   4  AVD no encontrado.
#   5  Instrumented tests fallaron.
#
# EJEMPLO:
#   bash bash/functions/pipelines/run_kotlin_app_tests.sh apps/my_app
#   bash bash/functions/pipelines/run_kotlin_app_tests.sh apps/my_app Pixel_7_API_34
#   bash bash/functions/pipelines/run_kotlin_app_tests.sh apps/my_app --skip-emulator
#   bash bash/functions/pipelines/run_kotlin_app_tests.sh apps/my_app Medium_Phone_API_35 --no-stop

set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REGISTRY_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"

# ---------------------------------------------------------------------------
# Parseo de argumentos
# ---------------------------------------------------------------------------

PROJECT_DIR="${1:-}"
AVD_NAME="Medium_Phone_API_35"
SKIP_EMULATOR=false
NO_STOP=false

# Primer argumento posicional es project_dir; el resto puede ser flags o avd_name.
shift || true

for arg in "$@"; do
    case "$arg" in
        --skip-emulator) SKIP_EMULATOR=true ;;
        --no-stop)       NO_STOP=true ;;
        --*)
            echo "[run_kotlin_app_tests] ERROR: flag desconocido: $arg" >&2
            echo "USO: $0 <project_dir> [avd_name] [--skip-emulator] [--no-stop]" >&2
            exit 1
            ;;
        *)  AVD_NAME="$arg" ;;
    esac
done

if [[ -z "$PROJECT_DIR" ]]; then
    echo "[run_kotlin_app_tests] ERROR: project_dir es obligatorio." >&2
    echo "USO: $0 <project_dir> [avd_name] [--skip-emulator] [--no-stop]" >&2
    exit 1
fi

# Resolver path absoluto
if [[ "$PROJECT_DIR" != /* ]]; then
    PROJECT_DIR="$(pwd)/$PROJECT_DIR"
fi

# ---------------------------------------------------------------------------
# Validacion inicial
# ---------------------------------------------------------------------------

if [[ ! -f "$PROJECT_DIR/gradlew" ]]; then
    echo "[run_kotlin_app_tests] ERROR: no se encontro gradlew en $PROJECT_DIR" >&2
    exit 1
fi

echo ""
echo "======================================================================"
echo " run_kotlin_app_tests"
echo "======================================================================"
echo " project_dir    : $PROJECT_DIR"
echo " avd_name       : $AVD_NAME"
echo " skip_emulator  : $SKIP_EMULATOR"
echo " no_stop        : $NO_STOP"
echo "======================================================================"
echo ""

# ---------------------------------------------------------------------------
# Tabla de resultados acumulada
# ---------------------------------------------------------------------------

# Arrays paralelos: nombre, status, tiempo
STEP_NAMES=()
STEP_STATUS=()
STEP_TIMES=()

record_step() {
    local name="$1" status="$2" elapsed="$3"
    STEP_NAMES+=("$name")
    STEP_STATUS+=("$status")
    STEP_TIMES+=("${elapsed}s")
}

print_summary() {
    echo ""
    echo "======================================================================"
    echo " RESUMEN"
    printf " %-30s  %-6s  %s\n" "STEP" "STATUS" "TIEMPO"
    echo " ------------------------------  ------  ------"
    for i in "${!STEP_NAMES[@]}"; do
        printf " %-30s  %-6s  %s\n" "${STEP_NAMES[$i]}" "${STEP_STATUS[$i]}" "${STEP_TIMES[$i]}"
    done
    echo "======================================================================"
    echo ""
}

# ---------------------------------------------------------------------------
# Paso 1: Unit tests (JVM)
# ---------------------------------------------------------------------------

echo "[run_kotlin_app_tests] [1/4] Unit tests (JVM)..."
T_START=$SECONDS
if bash "$REGISTRY_ROOT/bash/functions/infra/gradle_unit_test.sh" "$PROJECT_DIR"; then
    record_step "unit_tests" "OK" $((SECONDS - T_START))
    echo "[run_kotlin_app_tests] Unit tests: OK"
else
    record_step "unit_tests" "FAIL" $((SECONDS - T_START))
    print_summary
    echo "[run_kotlin_app_tests] ERROR: unit tests fallaron." >&2
    exit 1
fi

# ---------------------------------------------------------------------------
# Paso 2: Screenshot tests (Roborazzi, JVM)
# ---------------------------------------------------------------------------

echo ""
echo "[run_kotlin_app_tests] [2/4] Screenshot tests (Roborazzi, JVM)..."
T_START=$SECONDS
if bash "$REGISTRY_ROOT/bash/functions/infra/gradle_screenshot_test.sh" "$PROJECT_DIR"; then
    record_step "screenshot_tests" "OK" $((SECONDS - T_START))
    echo "[run_kotlin_app_tests] Screenshot tests: OK"
else
    record_step "screenshot_tests" "FAIL" $((SECONDS - T_START))
    print_summary
    echo "[run_kotlin_app_tests] ERROR: screenshot tests fallaron." >&2
    exit 2
fi

# ---------------------------------------------------------------------------
# Paso 3: Build APK debug
# ---------------------------------------------------------------------------

echo ""
echo "[run_kotlin_app_tests] [3/4] Build APK debug..."
T_START=$SECONDS
if bash "$REGISTRY_ROOT/bash/functions/infra/gradle_assemble_debug.sh" "$PROJECT_DIR"; then
    record_step "assemble_debug" "OK" $((SECONDS - T_START))
    echo "[run_kotlin_app_tests] Build APK: OK"
else
    record_step "assemble_debug" "FAIL" $((SECONDS - T_START))
    print_summary
    echo "[run_kotlin_app_tests] ERROR: build APK fallado." >&2
    exit 3
fi

# ---------------------------------------------------------------------------
# Paso 4: Instrumented tests (emulador)
# ---------------------------------------------------------------------------

if [[ "$SKIP_EMULATOR" == "true" ]]; then
    record_step "instrumented_tests" "SKIP" 0
    print_summary
    echo "[run_kotlin_app_tests] --skip-emulator activo. Pipeline completo (sin instrumented)."
    exit 0
fi

echo ""
echo "[run_kotlin_app_tests] [4/4] Instrumented tests en emulador '$AVD_NAME'..."

# Source adb_wsl para resolver $ADB y helpers de dispositivo
# shellcheck source=../infra/adb_wsl.sh
source "$REGISTRY_ROOT/bash/functions/infra/adb_wsl.sh"

# Verificar que el AVD existe
echo "[run_kotlin_app_tests] Verificando AVD '$AVD_NAME'..."
if ! bash "$REGISTRY_ROOT/bash/functions/infra/android_emulator_list.sh" | grep -qx "$AVD_NAME"; then
    record_step "emulator_check" "FAIL" 0
    record_step "instrumented_tests" "SKIP" 0
    print_summary
    echo "[run_kotlin_app_tests] ERROR: AVD '$AVD_NAME' no encontrado." >&2
    echo "  AVDs disponibles:" >&2
    bash "$REGISTRY_ROOT/bash/functions/infra/android_emulator_list.sh" | sed 's/^/    /' >&2
    exit 4
fi
record_step "emulator_check" "OK" 0

# Arrancar emulador (idempotente)
echo "[run_kotlin_app_tests] Arrancando emulador '$AVD_NAME' (idempotente)..."
T_START=$SECONDS
if ! bash "$REGISTRY_ROOT/bash/functions/infra/android_emulator_start.sh" "$AVD_NAME"; then
    record_step "emulator_start" "FAIL" $((SECONDS - T_START))
    print_summary
    echo "[run_kotlin_app_tests] ERROR: no se pudo arrancar el emulador." >&2
    exit 4
fi
record_step "emulator_start" "OK" $((SECONDS - T_START))

# Correr instrumented tests
echo "[run_kotlin_app_tests] Corriendo instrumented tests..."
T_START=$SECONDS
INSTRUMENTED_EXIT=0
bash "$REGISTRY_ROOT/bash/functions/infra/gradle_instrumented_test.sh" "$PROJECT_DIR" || INSTRUMENTED_EXIT=$?

if [[ $INSTRUMENTED_EXIT -eq 0 ]]; then
    record_step "instrumented_tests" "OK" $((SECONDS - T_START))
    echo "[run_kotlin_app_tests] Instrumented tests: OK"
else
    record_step "instrumented_tests" "FAIL" $((SECONDS - T_START))
fi

# Parar emulador (salvo --no-stop)
if [[ "$NO_STOP" == "false" ]]; then
    echo "[run_kotlin_app_tests] Parando emulador..."
    T_START=$SECONDS
    bash "$REGISTRY_ROOT/bash/functions/infra/android_emulator_stop.sh" || true
    record_step "emulator_stop" "OK" $((SECONDS - T_START))
else
    record_step "emulator_stop" "SKIP" 0
    echo "[run_kotlin_app_tests] --no-stop activo: emulador sigue corriendo."
fi

print_summary

if [[ $INSTRUMENTED_EXIT -ne 0 ]]; then
    echo "[run_kotlin_app_tests] ERROR: instrumented tests fallaron." >&2
    exit 5
fi

echo "[run_kotlin_app_tests] Pipeline e2e completado con exito."
exit 0
