#!/usr/bin/env bash
# telemetry_prelude — Wrapper de telemetria para funciones bash del registry.
# Issue 0085c-bash.
#
# Uso 1 (manual): source bash/functions/<dom>/<fn>.sh primero, despues source
#                 este archivo, y todas las funciones bash del registry
#                 quedaran envueltas con logging a call_monitor.operations.db.
#
# Uso 2 (auto):   exportar FN_TELEMETRY=1 antes de sourcear; este prelude
#                 detecta cada funcion definida que coincida con una funcion
#                 del registry (bash/functions/<dom>/<name>.sh) y la
#                 redefine como wrapper.
#
# Reglas:
#  - Idempotente: marca cada wrapper con flag _FN_T_WRAPPED_<name>=1; no
#    re-envuelve si ya esta envuelta.
#  - No-op silencioso si BD no existe o INSERT falla. NUNCA aborta el caller.
#  - Solo guarda function_id, duration_ms, success, error_class. NUNCA args.

if [ "${FN_TELEMETRY:-0}" != "1" ]; then
    return 0 2>/dev/null || exit 0
fi

# ---- Resolve registry root ----
_fn_t_root() {
    if [ -n "${FN_REGISTRY_ROOT:-}" ] && [ -f "$FN_REGISTRY_ROOT/registry.db" ]; then
        printf '%s' "$FN_REGISTRY_ROOT"
        return 0
    fi
    local d="${PWD}"
    while [ "$d" != "/" ]; do
        if [ -f "$d/registry.db" ]; then
            printf '%s' "$d"
            return 0
        fi
        d=$(dirname "$d")
    done
    return 1
}

# ---- Resolve operations.db ----
_FN_T_DB=""
_fn_t_resolve_db() {
    if [ -n "$_FN_T_DB" ] && [ -f "$_FN_T_DB" ]; then return 0; fi
    local root
    root=$(_fn_t_root) || return 1
    _FN_T_DB="$root/projects/fn_monitoring/apps/call_monitor/operations.db"
    if [ ! -f "$_FN_T_DB" ]; then
        _FN_T_DB=""
        return 1
    fi
    return 0
}

# ---- Log call ----
_fn_t_log() {
    local fn_id="$1" duration_ms="$2" success="$3" error_class="${4:-}"
    _fn_t_resolve_db || return 0
    command -v sqlite3 >/dev/null 2>&1 || return 0
    local sid="${CLAUDE_SESSION_ID:-}"
    local ts
    ts=$(date -u +%s)
    sid="${sid//\'/\'\'}"
    fn_id="${fn_id//\'/\'\'}"
    error_class="${error_class//\'/\'\'}"
    sqlite3 "$_FN_T_DB" "INSERT INTO calls (session_id, function_id, tool_used, args_hash, duration_ms, success, error_class, error_snippet, ts) VALUES ('$sid','$fn_id','bash_wrapper','',$duration_ms,$success,'$error_class','',$ts);" 2>/dev/null || true
}

# ---- Wrap a single function by name ----
_fn_t_wrap() {
    local orig="$1" fn_id="$2"

    # already wrapped?
    local guard
    guard="_FN_T_WRAPPED_${orig}"
    if [ "${!guard:-0}" = "1" ]; then return 0; fi

    # must exist as a function
    declare -F "$orig" >/dev/null 2>&1 || return 1

    # capture original body, rename to _fn_t_orig_<name>
    local body
    body=$(declare -f "$orig") || return 1
    # body starts with "<orig> ()"; prepend prefix to rename
    local renamed="_fn_t_orig_${body}"
    eval "$renamed"

    # define wrapper with the original name
    eval "
${orig}() {
    local _t0_ms _t1_ms _rc _dur
    _t0_ms=\$(date +%s%3N)
    _fn_t_orig_${orig} \"\$@\"
    _rc=\$?
    _t1_ms=\$(date +%s%3N)
    _dur=\$((_t1_ms - _t0_ms))
    if [ \$_rc -eq 0 ]; then
        _fn_t_log \"${fn_id}\" \$_dur 1 \"\"
    else
        _fn_t_log \"${fn_id}\" \$_dur 0 \"exit_\$_rc\"
    fi
    return \$_rc
}
"
    eval "$guard=1"
}

# ---- Auto-wrap: walk bash/functions and wrap every function currently defined ----
_fn_t_autowrap() {
    local root
    root=$(_fn_t_root) || return 1
    local f domain name fn_id
    while IFS= read -r f; do
        domain=$(basename "$(dirname "$f")")
        name=$(basename "$f" .sh)
        fn_id="${name}_bash_${domain}"
        if declare -F "$name" >/dev/null 2>&1; then
            _fn_t_wrap "$name" "$fn_id"
        fi
    done < <(find "$root/bash/functions" -type f -name '*.sh' 2>/dev/null)
}

# ---- Run autowrap on source ----
_fn_t_autowrap
