# Propuesta e2e_checks para apps/primitives_gallery
# Generado por fn-recopilador modo design-e2e
# Issue: 0121a wave 2
# Fecha: 2026-05-19
#
# Diagnostico:
#   lang=cpp, framework=imgui (fn::run_app), domain=gfx
#   toolchain: mingw-w64 (cross-compile Windows desde WSL)
#   modulos: main.cpp + capture.cpp + demo.cpp + 12 demos_*.cpp
#             + 44 .cpp del registry (core + viz + gfx — el set mas grande del ecosistema)
#   demos catalogadas: 43 entradas en k_demos[] (k_demo_count = 43)
#     Core (20): button, icon_button, toolbar, modal_dialog, text_input, select, toast,
#                tree_view, badge, empty_state, page_header, dashboard_panel, kpi_card,
#                text_editor, file_watcher, process_runner, tween, bezier_editor,
#                timeline, sql_workbench
#     Viz (20): bar_chart, pie_chart, line_plot, scatter_plot, histogram, sparkline,
#               graph_viewport, graph_styles, candlestick, gauge, heatmap, table_view,
#               surface_plot_3d, scatter_3d, mesh_viewer, treemap, sankey, chord,
#               contour, voronoi
#     Gfx (3):  shader_canvas, gl_texture, gl_info
#   deps externas: SQLite::SQLite3, stb (vendor), imgui_text_edit (vendor)
#   persistencia propia: ninguna (no BD, no state files)
#   sin tests/ ni tests_*.py
#   sin tag 'service': no expone HTTP (smoke con health: OMITIDO)
#   operations.db: NO usa (ops_audit: OMITIDO)
#
#   FLAG --capture:
#     Confirmado en main.cpp (L186-215): rama headless que crea ventana GLFW
#     GLFW_VISIBLE=FALSE + GL 3.3 core (deliberadamente baja para WSL Mesa/llvmpipe).
#     Requiere contexto OpenGL real. En WSL sin GPU: LIBGL_ALWAYS_SOFTWARE=1 (Mesa).
#     En WSL sin display (headless puro): GLFW requiere $DISPLAY o EGL offscreen.
#     La severidad de capture_mode se marca WARNING (no critical) porque WSL2 sin
#     libGL Mesa puede no entregar contexto GL valido — el check diagnostica pero
#     no bloquea el build gate si el entorno no tiene driver GL.
#
#   FLAG --list-demos: NO existe. main.cpp no tiene subcomando de listado.
#     demos_count: OMITIDO — no hay forma de obtener el conteo sin invocar GL.
#     Alternativa implementada: demos_count_static verifica el conteo en fuente.
#
# Patron: C++ ImGui app con modo --capture headless-GL

app_id: primitives_gallery

e2e_checks:
  # Build del target completo para Windows via mingw-w64.
  # primitives_gallery es el artefacto con mayor numero de .cpp del registry
  # enlazados (44 archivos: core + viz + gfx). Si cualquier funcion del registry
  # rompe su API de compilacion, este check lo detecta antes de que otro app falle.
  # Actua como build gate del registry de funciones C++.
  - id: build
    cmd: "cmake --build /home/lucas/fn_registry/cpp/build/windows --target primitives_gallery -j"
    timeout_s: 300
    severity: critical

  # Verifica que el artefacto .exe existe tras el build.
  # El build puede reportar exit 0 con -j en builds parciales sin producir binario.
  # Sin este check, capture_mode fallaria con un mensaje de error menos claro.
  - id: binary_exists
    cmd: "test -f /home/lucas/fn_registry/cpp/build/windows/apps/primitives_gallery/primitives_gallery.exe"
    timeout_s: 5
    severity: critical

  # Modo --capture headless: crea ventana GLFW VISIBLE=FALSE + GL 3.3 core,
  # renderiza las 43 demos en offscreen framebuffer y guarda PNG en /tmp/.
  # Confirma que: (a) todas las demos compilan y se ejecutan sin crash,
  # (b) el pipeline capture.cpp funciona hasta stbi_write_png,
  # (c) ninguna demo provoca SIGSEGV/assertion al primer frame (warmup=3).
  #
  # Requiere contexto OpenGL real. En WSL sin GPU usar:
  #   LIBGL_ALWAYS_SOFTWARE=1 (Mesa/llvmpipe) — disponible si mesa-utils instalado.
  # Si el entorno no puede entregar GL context, glfwCreateWindow retorna NULL y
  # el binario sale con exit 1 (ver capture.cpp L62-68).
  # Marcado WARNING porque la disponibilidad de GL en CI/WSL headless no esta
  # garantizada sin configuracion extra del entorno.
  #
  # El check verifica que se genero al menos un PNG (button.png es el primero).
  # Una suite completa de 43 PNGs indica que todas las demos son estables.
  - id: capture_mode
    cmd: >
      mkdir -p /tmp/primitives_gallery_e2e &&
      /home/lucas/fn_registry/cpp/build/windows/apps/primitives_gallery/primitives_gallery.exe
      --capture /tmp/primitives_gallery_e2e
    timeout_s: 120
    severity: warning
    # Nota: en WSL2 sin GPU puede necesitar LIBGL_ALWAYS_SOFTWARE=1 prefijado.
    # Si el entorno tiene Mesa: prepend "LIBGL_ALWAYS_SOFTWARE=1" al cmd.
    # Sin GL disponible, la demo gl_info y shader_canvas pueden fallar pero
    # las demas (Core/Viz) deben seguir siendo capturadas si GL 3.3 esta disponible.

  # Verifica que el capture produjo PNGs para las 43 demos catalogadas en k_demos[].
  # Cada demo debe generar un PNG nombrado por su id (ej. button.png, bar_chart.png).
  # Este check distingue "capture arranco y capturo algo" (capture_mode) de
  # "capture completo todas las demos sin skip". Se puede ejecutar solo si
  # capture_mode paso.
  # Cuenta archivos .png en el dir de salida y compara con k_demo_count=43.
  - id: capture_completeness
    cmd: >
      count=$(ls /tmp/primitives_gallery_e2e/*.png 2>/dev/null | wc -l);
      echo "PNG count: $count";
      test "$count" -ge 43
    timeout_s: 10
    severity: warning
    # Nota: depende de capture_mode. Si capture_mode fallo por falta de GL,
    # este check tambien fallara (warning, no bloquea gate).

  # Verifica que el .ico esta presente junto al fuente de la app.
  # add_imgui_app genera primitives_gallery_appicon.rc que windres incluye
  # como recurso (.rsrc) en el .exe. Si appicon.ico falta, el build pasa
  # pero el .exe queda sin icono embebido (visible en Explorer + taskbar).
  - id: icon_exists
    cmd: "test -f /home/lucas/fn_registry/apps/primitives_gallery/appicon.ico"
    timeout_s: 5
    severity: warning

  # Verifica estaticamente que el conteo de demos en fuente es consistente.
  # k_demo_count se deriva de sizeof(k_demos)/sizeof(k_demos[0]) en main.cpp.
  # Cuenta las entradas de DemoEntry en k_demos[] usando grep en main.cpp
  # como proxy — detecta si se añadio una demo al array pero no al modulo
  # demos_*.cpp (lo que provocaria un linker error en build, pero este check
  # da feedback mas temprano en el ciclo).
  # Referencia esperada: 43 entradas (conteo manual de k_demos[] en main.cpp L37-84).
  - id: demos_count_static
    cmd: >
      count=$(grep -c '^\s*{"' /home/lucas/fn_registry/apps/primitives_gallery/main.cpp);
      echo "DemoEntry count in source: $count";
      test "$count" -ge 43
    timeout_s: 5
    severity: warning
    # Nota: el grep cuenta lineas con '{"' en main.cpp — patron exclusivo de las
    # entradas de k_demos[]. Si el formato de k_demos[] cambia, revisar el patron.

# Justificacion por check:
# | check                | razon                                                                      |
# |----------------------|----------------------------------------------------------------------------|
# | build                | 44 .cpp del registry enlazados — build gate de API C++ del registry entero |
# | binary_exists        | confirma que cmake produjo .exe (no solo exit 0)                           |
# | capture_mode         | --capture es headless-GL (GLFW invisible + GL 3.3); confirma no-crash 43   |
# | capture_completeness | distingue "algo capturado" de "todas las demos completas"                  |
# | icon_exists          | .ico requerido para windres embeds — faltante no rompe build pero si deploy |
# | demos_count_static   | detecta drift entre k_demos[] en fuente y modulos demos_*.cpp              |
#
# checks OMITIDOS y razon:
# | check        | razon de omision                                                            |
# |-------------|-----------------------------------------------------------------------------|
# | ops_audit    | no usa operations.db                                                        |
# | smoke/health | no es service, no expone HTTP                                               |
# | demos_count  | --list-demos no existe en el binario; no hay forma headless sin GL           |
# | self_test    | fn::run_app no parsea --self-test; no implementado en main.cpp              |
