#pragma once

#include <string>
#include <vector>

// Registro estatico de enrichers (issue 0026).
//
// Al arrancar la app se escanea `<app_dir>/enrichers/*/manifest.yaml` y se
// rellena el registro. El context menu del viewport consulta
// `enrichers_for_type(type_ref)` para mostrar el submenu filtrado por tipo
// del nodo right-clickado.
//
// Los parametros declarados en `params:` del manifest se parsean para que
// la UI pueda renderizar un dialog de configuracion antes de lanzar el
// job. Si la lista esta vacia, el job se submitea directamente con `{}`.

namespace ge {

// Parametro declarado en `manifest.yaml` -> entrada `{ name, type, default }`.
// La UI de configuracion edita un buffer string por param y lo serializa a
// JSON segun el `type` al pulsar Run.
struct EnricherParam {
    std::string name;           // ej: "limit"
    std::string type;           // "int" | "float" | "string" | "bool"
    std::string default_value;  // valor por defecto en formato texto
    std::string description;    // opcional, para tooltip
};

struct EnricherSpec {
    std::string id;            // ej: "fetch_webpage"
    std::string name;          // ej: "Fetch web page"
    std::string description;
    std::vector<std::string> applies_to;   // tipos validos (case-insensitive)
    std::string run_path;      // path absoluto al ejecutable/script

    // Lenguaje del enricher (issue 0033 fase A). Determina como
    // jobs.cpp construye el argv del subprocess. Valores soportados:
    //   "python" (default si no se especifica) -> python <run_path>
    //   "go"                                   -> <run_path> directo
    //   "bash"                                 -> bash <run_path>
    std::string lang;

    // Basename del ejecutable o script (sin extension). El loader
    // resuelve <dir>/<exec_basename>{.py|.sh} o, para go,
    // <dir>/<exec_basename>{.exe} segun la plataforma. Default "run".
    std::string exec_basename;

    // Parametros editables por el usuario antes de lanzar el job.
    std::vector<EnricherParam> params;

    // Threshold opcional de auto-grouping (issue 0035e). Si > 0, el
    // enricher debe respetarlo al decidir cuando crear un Group con sus
    // resultados (vs dejarlos sueltos). Cuando es 0 / no declarado, el
    // enricher usa su default interno (DEFAULT_GROUP_THRESHOLD = 50).
    // Se propaga al runtime Python via campo `auto_group_threshold` del
    // JSON de stdin que jobs.cpp construye.
    int auto_group_threshold = 0;

    // True si lang != "" y no se pudo resolver el ejecutable
    // correspondiente (ej: enricher Go sin compilar). El loader deja
    // el spec en el registro pero marcado como deshabilitado para
    // que la UI pueda mostrar un warning.
    bool        disabled = false;
    std::string disabled_reason;
};

// Escanea el directorio. Reentrante (limpia el registro anterior). Devuelve
// el numero de enrichers cargados, -1 si el dir no existe.
int  enrichers_load(const char* enrichers_dir);

// Lista todos los enrichers cargados.
const std::vector<EnricherSpec>& enrichers_all();

// Filtra por tipo. Comparacion case-insensitive. Si applies_to es vacio en el
// manifest, el enricher se considera global (aplica a cualquier tipo).
std::vector<EnricherSpec> enrichers_for_type(const char* type_ref);

// Resuelve un enricher por id. Devuelve nullptr si no existe.
const EnricherSpec* enricher_by_id(const char* id);

} // namespace ge
