#!/bin/bash
[ "${PAI_WORKER:-}" = "1" ] && exit 0  # disposable worker: no per-session bookkeeping
# PAI Knowledge OS — pre-compact hook
#
# Called by Claude Code before context compaction.
# Updates session status to 'compacted' and logs the event.
#
# NEVER exits non-zero — this must not interrupt Claude Code.

PAI_OS="pai"

# Set tab color to working state while compacting
TAB_COLOR="${ADAPTER_DIR:-${PAI_DIR:-$HOME/.claude}}/tab-color-command.sh"
[[ -x "$TAB_COLOR" ]] && "$TAB_COLOR" working

# Bail gracefully if pai is not installed
command -v "$PAI_OS" &>/dev/null || exit 0
command -v sqlite3 &>/dev/null || exit 0

# PAI_HOME (~/.claude/pai by default — see src/config/pai-home.ts), falling
# back to the pre-2026-09-19 ~/.pai/registry.db.
REGISTRY_DB="${PAI_HOME:-$HOME/.claude/pai}/registry.db"
[ -f "$REGISTRY_DB" ] || REGISTRY_DB="$HOME/.pai/registry.db"
[ -f "$REGISTRY_DB" ] || exit 0

# ---------------------------------------------------------------------------
# Detect current project
# ---------------------------------------------------------------------------

DETECT_JSON=$("$PAI_OS" project detect --json 2>/dev/null) || exit 0
[ -z "$DETECT_JSON" ] && exit 0

# Parse slug — try jq first, fall back to python3
if command -v jq &>/dev/null; then
  PROJECT_SLUG=$(echo "$DETECT_JSON" | jq -r '.slug // empty' 2>/dev/null)
else
  PROJECT_SLUG=$(echo "$DETECT_JSON" | python3 -c \
    "import sys,json; d=json.load(sys.stdin); print(d.get('slug',''))" 2>/dev/null) || true
fi

[ -z "$PROJECT_SLUG" ] && exit 0

# ---------------------------------------------------------------------------
# Look up project and latest open session
# ---------------------------------------------------------------------------

PROJECT_ID=$(sqlite3 "$REGISTRY_DB" \
  "SELECT id FROM projects WHERE slug = '$PROJECT_SLUG' LIMIT 1" 2>/dev/null) || exit 0
[ -z "$PROJECT_ID" ] && exit 0

SESSION_ID=$(sqlite3 "$REGISTRY_DB" \
  "SELECT id FROM sessions WHERE project_id = $PROJECT_ID AND status = 'open' ORDER BY created_at DESC LIMIT 1" \
  2>/dev/null) || true

# ---------------------------------------------------------------------------
# Update session status to compacted
# ---------------------------------------------------------------------------

if [ -n "$SESSION_ID" ]; then
  sqlite3 "$REGISTRY_DB" \
    "UPDATE sessions SET status = 'compacted' WHERE id = $SESSION_ID" 2>/dev/null || true
fi

# ---------------------------------------------------------------------------
# Log to compaction_log
# ---------------------------------------------------------------------------

TS=$(date +%s)000

if [ -n "$SESSION_ID" ]; then
  sqlite3 "$REGISTRY_DB" \
    "INSERT INTO compaction_log (project_id, session_id, trigger, files_written, created_at) VALUES ($PROJECT_ID, $SESSION_ID, 'precompact', '', $TS)" \
    2>/dev/null || true
else
  sqlite3 "$REGISTRY_DB" \
    "INSERT INTO compaction_log (project_id, session_id, trigger, files_written, created_at) VALUES ($PROJECT_ID, NULL, 'precompact', '', $TS)" \
    2>/dev/null || true
fi

# ---------------------------------------------------------------------------
# Sync Obsidian vault
# ---------------------------------------------------------------------------

"$PAI_OS" obsidian sync 2>/dev/null || true

# ---------------------------------------------------------------------------
# Auto-checkpoint before context compression
# ---------------------------------------------------------------------------

"$PAI_OS" session checkpoint "Context compressing — auto-checkpoint" 2>/dev/null || true

# ---------------------------------------------------------------------------
# Generate handover brief before context compression
# ---------------------------------------------------------------------------
# Before compacting context, write a "## Continue" section to project's
# Notes/TODO.md with key items from this session so the next session
# can recover and pick up immediately if context is lost.
# If the command doesn't exist yet, fail gracefully.
#

"$PAI_OS" session handover "$PROJECT_SLUG" latest 2>/dev/null || true

exit 0
