#!/usr/bin/env python3
"""Save a session summary to Engram vault via HTTP API.

Called by agent hooks (Claude Code, Goose, Gemini) at session end.
Reads session context from stdin or arguments, posts to Engram save_memory MCP.

Usage:
    echo "summary" | python3 save_session_summary.py --agent claude
    python3 save_session_summary.py --agent goose --summary "msg"
"""

import argparse
import json
import os
import sys
import threading
import time
from datetime import datetime

ENGRAM_URL = os.environ.get("ENGRAM_URL", "http://127.0.0.1:8001")
# Only allow localhost or Tailscale (100.x.x.x) targets
if not (
    ENGRAM_URL.startswith("http://127.0.0.1")
    or ENGRAM_URL.startswith("http://localhost")
    or ENGRAM_URL.startswith("http://100.")
):
    print(
        f"ERROR: ENGRAM_URL must be localhost or Tailscale: {ENGRAM_URL}",
        file=sys.stderr,
    )
    sys.exit(1)
MCP_SSE = f"{ENGRAM_URL}/mcp/sse"
MCP_MSG = f"{ENGRAM_URL}/mcp/messages/"


def save_via_http(
    content: str,
    topics: list[str],
    summary: str,
    agent: str,
    importance: str = "medium",
) -> bool:
    """Save memory via Engram's MCP SSE protocol."""
    import queue

    import requests

    results = queue.Queue()

    def sse_reader(q):
        try:
            resp = requests.get(MCP_SSE, stream=True, timeout=10)
            for line in resp.iter_lines(decode_unicode=True):
                if line:
                    q.put(line)
        except Exception:
            pass

    t = threading.Thread(target=sse_reader, args=(results,), daemon=True)
    t.start()
    time.sleep(0.5)

    session_url = None
    while not results.empty():
        line = results.get()
        if line.startswith("data:"):
            path = line[5:].strip()
            if path.startswith("/"):
                session_url = f"{ENGRAM_URL}{path}"
            else:
                session_url = path
            break

    if not session_url:
        print("ERROR: Could not connect to Engram MCP", file=sys.stderr)
        return False

    # Initialize
    requests.post(
        session_url,
        json={
            "jsonrpc": "2.0",
            "id": 1,
            "method": "initialize",
            "params": {
                "protocolVersion": "2024-11-05",
                "capabilities": {},
                "clientInfo": {"name": f"engram-hook-{agent}", "version": "1.0"},
            },
        },
        timeout=5,
    )
    time.sleep(0.3)

    # Send initialized notification
    requests.post(
        session_url,
        json={"jsonrpc": "2.0", "method": "notifications/initialized"},
        timeout=5,
    )

    # Call save_memory
    ts = datetime.now().strftime("%Y-%m-%d %H:%M")
    full_content = f"[{agent.upper()} session — {ts}]\n\n{content}"
    requests.post(
        session_url,
        json={
            "jsonrpc": "2.0",
            "id": 2,
            "method": "tools/call",
            "params": {
                "name": "save_memory",
                "arguments": {
                    "content": full_content,
                    "topics": topics + [agent, "auto-save"],
                    "importance": importance,
                    "summary": summary,
                },
            },
        },
        timeout=10,
    )

    time.sleep(0.5)

    # Check response
    while not results.empty():
        line = results.get()
        if line.startswith("data:"):
            try:
                data = json.loads(line[5:].strip())
                if "result" in data:
                    content_list = data["result"].get("content", [])
                    for c in content_list:
                        if c.get("type") == "text":
                            result = json.loads(c["text"])
                            print(f"Saved: {result.get('path', '').split('/')[-1]}")
                            return True
            except Exception:
                pass

    print("WARNING: Save sent but no confirmation received", file=sys.stderr)
    return True


def main():
    parser = argparse.ArgumentParser(description="Save session summary to Engram")
    parser.add_argument("--agent", required=True, help="Agent name (claude, goose, gemini, hermes)")
    parser.add_argument("--summary", default="", help="One-line summary")
    parser.add_argument("--topics", default="", help="Comma-separated topics")
    parser.add_argument("--importance", default="medium", choices=["low", "medium", "high"])
    parser.add_argument("--content", default="", help="Full content (or read from stdin)")
    args = parser.parse_args()

    content = args.content
    if not content and not sys.stdin.isatty():
        content = sys.stdin.read().strip()
    if not content:
        content = args.summary or "Session ended — no summary provided"

    topics = [t.strip() for t in args.topics.split(",") if t.strip()] if args.topics else []
    summary = args.summary or content[:100]

    try:
        save_via_http(content, topics, summary, args.agent, args.importance)
    except Exception as e:
        print(f"ERROR: {e}", file=sys.stderr)
        sys.exit(1)


if __name__ == "__main__":
    main()
