#!/usr/bin/env python3
"""
Monitor realtime percakapan Hermes API server (semua yang masuk via HERMES_API_URL).

Cara pakai:
  python3 hermes-api-monitor.py            # pantau mulai dari sekarang
  python3 hermes-api-monitor.py --history  # tampilkan 10 pesan terakhir dulu
  python3 hermes-api-monitor.py --history 50
  MONITOR_POLL=1 python3 hermes-api-monitor.py   # polling lebih cepat (default 1.5s)

Data dibaca dari state.db (tabel messages JOIN sessions WHERE source='api_server')
— sesi yang sama dengan yang dipakai API server, jadi ini realtime sebenarnya.
"""
import sqlite3
import time
import sys
import os
import datetime

DB = os.environ.get('HERMES_STATE_DB', '/opt/data/state.db')
CURSOR = os.environ.get('MONITOR_CURSOR', '/tmp/hermes-api-monitor.cursor')
POLL = float(os.environ.get('MONITOR_POLL', '1.5'))

def load_cursor():
    try:
        with open(CURSOR) as f:
            return int(f.read().strip())
    except Exception:
        return None

def save_cursor(v):
    try:
        with open(CURSOR, 'w') as f:
            f.write(str(v))
    except Exception:
        pass

def fmt_time(ts):
    try:
        return datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S')
    except Exception:
        return datetime.datetime.now().strftime('%H:%M:%S')

def short_sid(sid):
    return sid if len(sid) <= 28 else sid[:28] + '…'

def print_msg(r):
    role = '👤 USER ' if r['role'] == 'user' else '🤖 AGENT'
    content = (r['content'] or '').replace('\n', ' ')
    if len(content) > 240:
        content = content[:240] + '…'
    print(f"[{fmt_time(r['timestamp'])}] [{short_sid(r['session_id'])}] {role}: {content}", flush=True)

def query_new(last_id):
    db = sqlite3.connect(DB, timeout=5)
    db.row_factory = sqlite3.Row
    rows = db.execute(
        """SELECT m.id, m.session_id, m.role, m.content, m.timestamp, s.source
           FROM messages m JOIN sessions s ON m.session_id = s.id
           WHERE m.id > ? AND s.source = 'api_server'
             AND m.role IN ('user','assistant')
             AND m.content IS NOT NULL AND trim(m.content) != ''
           ORDER BY m.id ASC""",
        (last_id,),
    ).fetchall()
    db.close()
    return rows

def show_history(n):
    db = sqlite3.connect(DB, timeout=5)
    db.row_factory = sqlite3.Row
    rows = db.execute(
        """SELECT m.id, m.session_id, m.role, m.content, m.timestamp
           FROM messages m JOIN sessions s ON m.session_id = s.id
           WHERE s.source = 'api_server' AND m.role IN ('user','assistant')
             AND m.content IS NOT NULL AND trim(m.content) != ''
           ORDER BY m.id DESC LIMIT ?""",
        (n,),
    ).fetchall()
    db.close()
    print(f"--- {len(rows)} pesan terakhir (historis) ---")
    for r in reversed(rows):
        print_msg(r)
    print("-------------------------------------")
    return rows[-1]['id'] if rows else None

def main():
    args = [a for a in sys.argv[1:]]
    last_id = load_cursor()
    if '--history' in args:
        try:
            n = int(args[args.index('--history') + 1])
        except (ValueError, IndexError):
            n = 10
        h = show_history(n)
        if last_id is None and h is not None:
            last_id = h
    if last_id is None:
        # Default: mulai dari pesan terbaru yang sudah ada (pantau ke depan saja)
        db = sqlite3.connect(DB, timeout=5)
        last_id = db.execute("SELECT COALESCE(MAX(id),0) FROM messages").fetchone()[0]
        db.close()
        save_cursor(last_id)

    print(f"[monitor] Memantau percakapan api_server di {DB} (mulai dari message id {last_id})", flush=True)
    print("[monitor] Ctrl+C untuk berhenti\n", flush=True)

    while True:
        try:
            rows = query_new(last_id)
            for r in rows:
                print_msg(r)
                last_id = r['id']
            if rows:
                save_cursor(last_id)
        except Exception as e:
            print(f"[monitor] error: {e}", file=sys.stderr, flush=True)
        time.sleep(POLL)

if __name__ == '__main__':
    main()
