#!/bin/bash
# vh_health.sh — БД и runtime смоук VakHunter. Запускать на mac mini.
# Output: компактный отчёт с ✅/❌ маркерами.
#
# Usage:
#   ssh -i ~/.ssh/id_ed25519 cebers_mini@Cebers-mini.local 'bash -s' < this_file
# Или скопировать в ~/.claude-tools/vh_health.sh и звать там.

set -u
DB="/Users/cebers_mini/Services/VakHunter/vakhunter.db"
ERR_LOG="/Users/cebers_mini/Services/shared/logs/vakhunter.error.log"
WD_LOG="/Users/cebers_mini/Services/shared/logs/vakhunter-watchdog.log"
LABEL="local.vakhunter"

emit() { echo "$1"; }
ok()   { emit "✅ $1"; }
fail() { emit "❌ $1"; }
info() { emit "ℹ️  $1"; }

emit "=== VakHunter health $(date '+%Y-%m-%d %H:%M:%S') ==="

# 1. launchd PID
PID=$(launchctl list | awk -v l="$LABEL" '$3==l {print $1}')
if [ -z "$PID" ] || [ "$PID" = "-" ]; then
    fail "launchd $LABEL не запущен"
else
    ok "launchd $LABEL running (PID $PID)"
fi

# 2. Последний scheduler tick — не должен быть «STALE» по watchdog логу
LAST_TICK_LINE=$(grep "Checking subscriptions" "$ERR_LOG" 2>/dev/null | tail -1)
if [ -z "$LAST_TICK_LINE" ]; then
    fail "scheduler ни разу не тикал"
else
    TS=$(echo "$LAST_TICK_LINE" | cut -d',' -f1)
    EPOCH=$(date -j -f "%Y-%m-%d %H:%M:%S" "$TS" "+%s" 2>/dev/null || echo 0)
    NOW=$(date "+%s")
    DIFF_MIN=$(( (NOW - EPOCH) / 60 ))
    if [ "$DIFF_MIN" -lt 35 ]; then
        ok "scheduler tick $DIFF_MIN мин назад (порог 35)"
    else
        fail "scheduler tick $DIFF_MIN мин назад — STALE"
    fi
fi

# 3. Watchdog kicks за последние 60 мин — НО игнорируем kicks до последнего
# bot start (после рестарта bot был свеж, новые kicks показатель проблемы)
LAST_BOT_START_TS=$(grep "Bot started" "$ERR_LOG" 2>/dev/null | tail -1 | cut -d',' -f1)
LAST_BOT_START_EPOCH=$(date -j -f "%Y-%m-%d %H:%M:%S" "$LAST_BOT_START_TS" "+%s" 2>/dev/null || echo 0)

LAST_STALE_TS=$(grep "STALE" "$WD_LOG" 2>/dev/null | tail -1 | awk -F'[][]' '{print $2}')
KICKS_AFTER_START=$(grep "STALE" "$WD_LOG" 2>/dev/null | tail -50 | \
    awk -F'[][]' '{print $2}' | while read ts; do
        e=$(date -j -f "%Y-%m-%d %H:%M:%S" "$ts" "+%s" 2>/dev/null || echo 0)
        [ "$e" -gt "$LAST_BOT_START_EPOCH" ] && echo 1
    done | wc -l | tr -d ' ')
if [ "$KICKS_AFTER_START" = "0" ]; then
    ok "watchdog НЕ убивал бот после последнего рестарта ($LAST_BOT_START_TS); последний STALE: ${LAST_STALE_TS:-никогда}"
else
    fail "watchdog убил бот $KICKS_AFTER_START раз после рестарта — kick-петля?"
fi

# 4. БД метрики
USERS=$(sqlite3 "$DB" 'SELECT COUNT(*) FROM users;' 2>/dev/null)
ACTIVE_SUBS=$(sqlite3 "$DB" 'SELECT COUNT(*) FROM subscriptions WHERE is_active=1;' 2>/dev/null)
BANNED=$(sqlite3 "$DB" 'SELECT COUNT(*) FROM users WHERE is_banned=1;' 2>/dev/null)
info "users=$USERS, active_subs=$ACTIVE_SUBS, banned=$BANNED"

# 5. Sent vacancies за 24h (если активных подписок нет — слать некому, это info)
SENT_24=$(sqlite3 "$DB" "SELECT COUNT(*) FROM sent_vacancies WHERE sent_at >= datetime('now','-1 day');" 2>/dev/null)
SENT_7=$(sqlite3 "$DB" "SELECT COUNT(*) FROM sent_vacancies WHERE sent_at >= datetime('now','-7 day');" 2>/dev/null)
if [ "${ACTIVE_SUBS:-0}" = "0" ]; then
    info "sent_vacancies 7d=$SENT_7 — активных подписок 0, рассылать некому (не ошибка)"
elif [ "$SENT_24" -gt 0 ] 2>/dev/null; then
    ok "sent_vacancies 24h=$SENT_24, 7d=$SENT_7"
elif [ "$SENT_7" -gt 0 ] 2>/dev/null; then
    fail "sent_vacancies 24h=0 (за 7д было $SENT_7) — рассылки замерли"
else
    fail "sent_vacancies 7d=0 при active_subs=$ACTIVE_SUBS — рассылки не работают"
fi

# 6. Vacancies fetched за 7д + diversity
emit "--- vacancies fetched 7d by source ---"
sqlite3 -column "$DB" "SELECT source, COUNT(*) FROM vacancies WHERE created_at >= datetime('now','-7 day') GROUP BY source ORDER BY 2 DESC;" 2>/dev/null
N_SOURCES=$(sqlite3 "$DB" "SELECT COUNT(DISTINCT source) FROM vacancies WHERE created_at >= datetime('now','-7 day');" 2>/dev/null)
if [ "$N_SOURCES" -ge 3 ] 2>/dev/null; then
    ok "$N_SOURCES уникальных источников за 7д"
else
    fail "только $N_SOURCES источник(ов) — большинство парсеров мёртвые"
fi

# 7. Parsers smoke последний
LAST_SMOKE=$(grep "parsers-smoke.*DONE" "$ERR_LOG" 2>/dev/null | tail -1)
if [ -n "$LAST_SMOKE" ]; then
    info "smoke: $(echo "$LAST_SMOKE" | sed 's/.*DONE //')"
    FAILED=$(echo "$LAST_SMOKE" | grep -oE 'failed_list=[^ ]*' | cut -d= -f2)
    case "$FAILED" in
        ""|"kwork"|"superjob"|"kwork,superjob"|"superjob,kwork")
            ok "parsers smoke в норме (kwork/superjob known-flaky)" ;;
        *)
            fail "parsers smoke новые падения: $FAILED" ;;
    esac
else
    fail "parsers smoke ни разу не запускался"
fi

# 8. Новые юзеры за 3 дня — есть ли «брошенные онбординги»
emit "--- новые юзеры 3 дня ---"
sqlite3 -column -header "$DB" "SELECT user_id, COALESCE(username,'-') AS username, datetime(created_at) AS reg, onboarding_completed AS onb_ok FROM users WHERE created_at >= datetime('now','-3 day') AND (username IS NULL OR username NOT LIKE '%TestUser%') ORDER BY created_at DESC LIMIT 10;" 2>/dev/null

emit "=== health complete ==="
