#!/bin/bash
# TODO: Add `set -u` to catch undefined variable usage early
# SpecMem Brain Health Monitor
# Checks postgres, embedding, translate, minicot sockets
# Writes /data/run/health.json every 10 seconds
# AUTO-SHUTDOWN: If no socket activity for 10 minutes, kill the container

IDLE_TIMEOUT=${SPECMEM_IDLE_TIMEOUT:-900}  # 15 minutes default
HEARTBEAT_FILE="/data/run/.brain-heartbeat"
LAST_ACTIVITY=$(date +%s)

# Touch heartbeat on startup
touch "$HEARTBEAT_FILE"

while true; do
    PG_OK="false"; EMBED_OK="false"; TRANSLATE_OK="false"; MINICOT_OK="false"

    if [ -S /data/run/.s.PGSQL.5432 ]; then
        # TODO: Cache psql path instead of finding on every iteration (performance)
        PSQL=$(find /usr/lib/postgresql -name psql -type f 2>/dev/null | head -1)
        if "$PSQL" -h /data/run -U specmem -d specmem -c "SELECT 1" >/dev/null 2>&1; then
            PG_OK="true"
        fi
    fi

    # Check sockets exist AND are responsive using a simple python one-liner
    check_socket() {
        local sock_path="$1"
        if [ -S "$sock_path" ]; then
            timeout 8 python3 -c "
import socket, sys
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.settimeout(5)
try:
    s.connect('$sock_path')
    s.sendall(b'ping\n')
    data = s.recv(4096)
    sys.exit(0) if data else sys.exit(1)
except:
    sys.exit(1)
" 2>/dev/null
            return $?
        fi
        return 1
    }

    if check_socket "/data/run/embed.sock"; then
        EMBED_OK="true"
    fi
    if check_socket "/data/run/translate.sock"; then
        TRANSLATE_OK="true"
    fi
    if check_socket "/data/run/minicot.sock"; then
        MINICOT_OK="true"
    fi

    STATUS="healthy"
    [ "$PG_OK" = "false" ] && STATUS="degraded"
    [ "$EMBED_OK" = "false" ] && STATUS="degraded"

    NOW=$(date +%s)

    # Check if host has touched heartbeat file (MCP bootstrap touches it on connect)
    # TODO: Use portable stat syntax (stat -c is Linux-only, use stat -f on macOS)
    if [ -f "$HEARTBEAT_FILE" ]; then
        HB_TIME=$(stat -c %Y "$HEARTBEAT_FILE" 2>/dev/null || echo "0")
        if [ "$HB_TIME" -gt "$LAST_ACTIVITY" ]; then
            LAST_ACTIVITY=$HB_TIME
        fi
    fi

    IDLE_SECONDS=$((NOW - LAST_ACTIVITY))

    # Auto-shutdown if idle too long (Claude dead for 10+ minutes)
    if [ "$IDLE_TIMEOUT" -gt 0 ] && [ "$IDLE_SECONDS" -ge "$IDLE_TIMEOUT" ]; then
        echo "[healthcheck] Brain idle for ${IDLE_SECONDS}s (timeout: ${IDLE_TIMEOUT}s) — shutting down" >&2
        printf '{"status":"shutdown","timestamp":"%s","reason":"idle_timeout","idle_seconds":%d}\n' \
            "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$IDLE_SECONDS" > /data/run/health.json
        # Kill supervisord (PID 1) which stops all services and exits container
        kill 1
        exit 0
    fi

    printf '{"status":"%s","timestamp":"%s","postgres":"%s","embedding":"%s","translate":"%s","minicot":"%s","uptime_seconds":%d,"idle_seconds":%d}\n' \
        "$STATUS" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$PG_OK" "$EMBED_OK" "$TRANSLATE_OK" "$MINICOT_OK" "$SECONDS" "$IDLE_SECONDS" \
        > /data/run/health.json

    sleep 10
done
